|
@@ -2,8 +2,11 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
|
|
|
|
|
|
| 5 |
"errors"
|
| 6 |
"fmt"
|
|
|
|
| 7 |
"net"
|
| 8 |
"strconv"
|
| 9 |
"strings"
|
|
@@ -64,6 +71,9 @@
|
|
| 64 |
srv *grpc.Server
|
| 65 |
ctx context.Context
|
| 66 |
exit context.CancelFunc
|
|
|
|
|
|
|
|
|
|
| 67 |
}
|
| 68 |
|
| 69 |
// New creates a new aggregator.
|
|
@@ -72,6 +82,8 @@
|
|
| 72 |
stateInterface stateInterface,
|
| 73 |
ethTxManager ethTxManager,
|
| 74 |
etherman etherman,
|
|
|
|
|
|
|
| 75 |
) (Aggregator, error) {
|
| 76 |
var profitabilityChecker aggregatorTxProfitabilityChecker
|
| 77 |
switch cfg.TxProfitabilityCheckerType {
|
|
@@ -93,6 +105,9 @@
|
|
| 93 |
TimeCleanupLockedProofs: cfg.CleanupLockedProofsInterval,
|
| 94 |
|
| 95 |
finalProof: make(chan finalProofMsg),
|
|
|
|
|
|
|
|
|
|
| 96 |
}
|
| 97 |
|
| 98 |
return a, nil
|
|
@@ -116,7 +131,7 @@
|
|
| 116 |
}, nil)
|
| 117 |
|
| 118 |
// Delete ungenerated recursive proofs
|
| 119 |
-
err := a.State.
|
| 120 |
if err != nil {
|
| 121 |
return fmt.Errorf("failed to initialize proofs cache %w", err)
|
| 122 |
}
|
|
@@ -212,46 +227,819 @@
|
|
| 212 |
_, err = a.tryBuildFinalProof(ctx, prover, nil)
|
| 213 |
if err != nil {
|
| 214 |
log.Errorf("Error checking proofs to verify: %v", err)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
}
|
| 216 |
|
| 217 |
-
proofGenerated, err := a.
|
| 218 |
if err != nil {
|
| 219 |
-
log.Errorf("Error trying to aggregate
|
| 220 |
}
|
| 221 |
-
|
| 222 |
if !proofGenerated {
|
| 223 |
-
proofGenerated, err = a.
|
| 224 |
if err != nil {
|
| 225 |
-
log.Errorf("Error trying to generate
|
| 226 |
}
|
| 227 |
}
|
| 228 |
-
|
| 229 |
if !proofGenerated {
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
}
|
| 235 |
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
}
|
| 241 |
}
|
| 242 |
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
}
|
| 248 |
}
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
}
|
| 254 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
}
|
| 256 |
|
| 257 |
// canVerifyProof returns true if we have reached the timeout to verify a proof
|
|
@@ -285,41 +1073,41 @@
|
|
| 285 |
|
| 286 |
// isSynced checks if the state is synchronized with L1. If a batch number is
|
| 287 |
// provided, it makes sure that the state is synced with that batch.
|
| 288 |
-
func (a *Aggregator) isSynced(ctx context.Context, batchNum *uint64) bool {
|
| 289 |
// get latest verified batch as seen by the synchronizer
|
| 290 |
lastVerifiedBatch, err := a.State.GetLastVerifiedBatch(ctx, nil)
|
| 291 |
if err == state.ErrNotFound {
|
| 292 |
-
return false
|
| 293 |
}
|
| 294 |
if err != nil {
|
| 295 |
log.Warnf("Failed to get last consolidated batch: %v", err)
|
| 296 |
-
return false
|
| 297 |
}
|
| 298 |
|
| 299 |
if lastVerifiedBatch == nil {
|
| 300 |
-
return false
|
| 301 |
}
|
| 302 |
|
| 303 |
if batchNum != nil && lastVerifiedBatch.BatchNumber < *batchNum {
|
| 304 |
log.Infof("Waiting for the state to be synced, lastVerifiedBatchNum: %d, waiting for batch: %d", lastVerifiedBatch.BatchNumber, batchNum)
|
| 305 |
-
return false
|
| 306 |
}
|
| 307 |
|
| 308 |
// latest verified batch in L1
|
| 309 |
lastVerifiedEthBatchNum, err := a.Ethman.GetLatestVerifiedBatchNum()
|
| 310 |
if err != nil {
|
| 311 |
log.Warnf("Failed to get last eth batch, err: %v", err)
|
| 312 |
-
return false
|
| 313 |
}
|
| 314 |
|
| 315 |
// check if L2 is synced with L1
|
| 316 |
if lastVerifiedBatch.BatchNumber < lastVerifiedEthBatchNum {
|
| 317 |
log.Infof("Waiting for the state to be synced, lastVerifiedBatchNum: %d, lastVerifiedEthBatchNum: %d, waiting for batch",
|
| 318 |
lastVerifiedBatch.BatchNumber, lastVerifiedEthBatchNum)
|
| 319 |
-
return false
|
| 320 |
}
|
| 321 |
|
| 322 |
-
return true
|
| 323 |
}
|
| 324 |
|
| 325 |
func (a *Aggregator) buildInputProver(ctx context.Context, batchToVerify *state.Batch) (*prover.InputProver, error) {
|
|
@@ -383,10 +1171,10 @@
|
|
| 383 |
}
|
| 384 |
if l1InfoRoot != nil && *l1InfoRoot != calculatedL1InfoRoot {
|
| 385 |
for i, l := range aLeaves {
|
| 386 |
-
log.
|
| 387 |
}
|
| 388 |
for i, s := range smtProof {
|
| 389 |
-
log.
|
| 390 |
}
|
| 391 |
return nil, fmt.Errorf("error: l1InfoRoot mismatch. L1InfoRoot: %s, calculatedL1InfoRoot: %s. l1InfoTreeIndex: %d", l1InfoRoot.String(), calculatedL1InfoRoot.String(), l2blockRaw.IndexL1InfoTree)
|
| 392 |
}
|
|
@@ -513,19 +1301,37 @@
|
|
| 513 |
|
| 514 |
// wait for the synchronizer to catch up the verified batches
|
| 515 |
log.Debug("A final proof has been sent, waiting for the network to be synced")
|
| 516 |
-
|
| 517 |
-
log.
|
| 518 |
-
|
| 519 |
}
|
| 520 |
|
| 521 |
// network is synced with the final proof, we can safely delete all recursive
|
| 522 |
// proofs up to the last synced batch
|
| 523 |
-
err = a.State.
|
| 524 |
if err != nil {
|
| 525 |
log.Errorf("Failed to store proof aggregation result: %v", err)
|
| 526 |
}
|
| 527 |
}
|
| 528 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 529 |
func buildMonitoredTxID(batchNumber, batchNumberFinal uint64) string {
|
| 530 |
return fmt.Sprintf(monitoredIDFormat, batchNumber, batchNumberFinal)
|
| 531 |
}
|
|
@@ -536,7 +1342,7 @@
|
|
| 536 |
case <-a.ctx.Done():
|
| 537 |
return
|
| 538 |
case <-time.After(a.TimeCleanupLockedProofs.Duration):
|
| 539 |
-
n, err := a.State.
|
| 540 |
if err != nil {
|
| 541 |
log.Errorf("Failed to cleanup locked proofs: %v", err)
|
| 542 |
}
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
+
"encoding/json"
|
| 7 |
"errors"
|
| 8 |
"fmt"
|
| 9 |
+
"math/big"
|
| 10 |
"net"
|
| 11 |
"strconv"
|
| 12 |
"strings"
|
|
|
|
| 71 |
srv *grpc.Server
|
| 72 |
ctx context.Context
|
| 73 |
exit context.CancelFunc
|
| 74 |
+
|
| 75 |
+
AggLayerClient client.ClientInterface
|
| 76 |
+
sequencerPrivateKey *ecdsa.PrivateKey
|
| 77 |
}
|
| 78 |
|
| 79 |
// New creates a new aggregator.
|
|
|
|
| 82 |
stateInterface stateInterface,
|
| 83 |
ethTxManager ethTxManager,
|
| 84 |
etherman etherman,
|
| 85 |
+
agglayerClient client.ClientInterface,
|
| 86 |
+
sequencerPrivateKey *ecdsa.PrivateKey,
|
| 87 |
) (Aggregator, error) {
|
| 88 |
var profitabilityChecker aggregatorTxProfitabilityChecker
|
| 89 |
switch cfg.TxProfitabilityCheckerType {
|
|
|
|
| 105 |
TimeCleanupLockedProofs: cfg.CleanupLockedProofsInterval,
|
| 106 |
|
| 107 |
finalProof: make(chan finalProofMsg),
|
| 108 |
+
|
| 109 |
+
AggLayerClient: agglayerClient,
|
| 110 |
+
sequencerPrivateKey: sequencerPrivateKey,
|
| 111 |
}
|
| 112 |
|
| 113 |
return a, nil
|
|
|
|
| 131 |
}, nil)
|
| 132 |
|
| 133 |
// Delete ungenerated recursive proofs
|
| 134 |
+
err := a.State.DeleteUngeneratedProofs(ctx, nil)
|
| 135 |
if err != nil {
|
| 136 |
return fmt.Errorf("failed to initialize proofs cache %w", err)
|
| 137 |
}
|
|
|
|
| 227 |
_, err = a.tryBuildFinalProof(ctx, prover, nil)
|
| 228 |
if err != nil {
|
| 229 |
log.Errorf("Error checking proofs to verify: %v", err)
|
| 230 |
+
|
| 231 |
+
if errors.Is(err, context.Canceled) {
|
| 232 |
+
// the context was canceled, just continue, the loop will stop in the <-ctx.Done() case
|
| 233 |
+
continue
|
| 234 |
+
}
|
| 235 |
}
|
| 236 |
|
| 237 |
+
proofGenerated, err := a.tryAggregateProofs(ctx, prover)
|
| 238 |
if err != nil {
|
| 239 |
+
log.Errorf("Error trying to aggregate proofs: %v", err)
|
| 240 |
}
|
|
|
|
| 241 |
if !proofGenerated {
|
| 242 |
+
proofGenerated, err = a.tryGenerateBatchProof(ctx, prover)
|
| 243 |
if err != nil {
|
| 244 |
+
log.Errorf("Error trying to generate proof: %v", err)
|
| 245 |
}
|
| 246 |
}
|
|
|
|
| 247 |
if !proofGenerated {
|
| 248 |
+
// if no proof was generated (aggregated or batch) wait some time before retry
|
| 249 |
+
time.Sleep(a.cfg.RetryTime.Duration)
|
| 250 |
+
} // if proof was generated we retry immediately as probably we have more proofs to process
|
| 251 |
+
}
|
| 252 |
+
}
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
// This function waits to receive a final proof from a prover. Once it receives
|
| 256 |
+
// the proof, it performs these steps in order:
|
| 257 |
+
// - send the final proof to L1
|
| 258 |
+
// - wait for the synchronizer to catch up
|
| 259 |
+
// - clean up the cache of recursive proofs
|
| 260 |
+
func (a *Aggregator) sendFinalProof() {
|
| 261 |
+
for {
|
| 262 |
+
select {
|
| 263 |
+
case <-a.ctx.Done():
|
| 264 |
+
return
|
| 265 |
+
case msg := <-a.finalProof:
|
| 266 |
+
ctx := a.ctx
|
| 267 |
+
proof := msg.recursiveProof
|
| 268 |
+
|
| 269 |
+
log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 270 |
+
log.Info("Verifying final proof with ethereum smart contract")
|
| 271 |
+
|
| 272 |
+
a.startProofVerification()
|
| 273 |
+
|
| 274 |
+
finalBatch, err := a.State.GetBatchByNumber(ctx, proof.BatchNumberFinal, nil)
|
| 275 |
+
if err != nil {
|
| 276 |
+
log.Errorf("Failed to retrieve batch with number [%d]: %v", proof.BatchNumberFinal, err)
|
| 277 |
+
a.endProofVerification()
|
| 278 |
+
continue
|
| 279 |
}
|
| 280 |
|
| 281 |
+
inputs := ethmanTypes.FinalProofInputs{
|
| 282 |
+
FinalProof: msg.finalProof,
|
| 283 |
+
NewLocalExitRoot: finalBatch.LocalExitRoot.Bytes(),
|
| 284 |
+
NewStateRoot: finalBatch.StateRoot.Bytes(),
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
log.Infof("Final proof inputs: NewLocalExitRoot [%#x], NewStateRoot [%#x]", inputs.NewLocalExitRoot, inputs.NewStateRoot)
|
| 288 |
+
|
| 289 |
+
switch a.cfg.SettlementBackend {
|
| 290 |
+
case AggLayer:
|
| 291 |
+
if success := a.settleWithAggLayer(ctx, proof, inputs); !success {
|
| 292 |
+
continue
|
| 293 |
+
}
|
| 294 |
+
default:
|
| 295 |
+
if success := a.settleDirect(ctx, proof, inputs); !success {
|
| 296 |
+
continue
|
| 297 |
}
|
| 298 |
}
|
| 299 |
|
| 300 |
+
a.resetVerifyProofTime()
|
| 301 |
+
a.endProofVerification()
|
| 302 |
+
}
|
| 303 |
+
}
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
func (a *Aggregator) settleDirect(
|
| 307 |
+
ctx context.Context,
|
| 308 |
+
proof *state.Proof,
|
| 309 |
+
inputs ethmanTypes.FinalProofInputs,
|
| 310 |
+
) (success bool) {
|
| 311 |
+
// add batch verification to be monitored
|
| 312 |
+
sender := common.HexToAddress(a.cfg.SenderAddress)
|
| 313 |
+
|
| 314 |
+
to, data, err := a.Ethman.BuildTrustedVerifyBatchesTxData(
|
| 315 |
+
proof.BatchNumber-1,
|
| 316 |
+
proof.BatchNumberFinal,
|
| 317 |
+
&inputs,
|
| 318 |
+
sender,
|
| 319 |
+
)
|
| 320 |
+
if err != nil {
|
| 321 |
+
log.Errorf("Error estimating batch verification to add to eth tx manager: %v", err)
|
| 322 |
+
a.handleFailureToAddVerifyBatchToBeMonitored(ctx, proof)
|
| 323 |
+
|
| 324 |
+
return false
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
monitoredTxID := buildMonitoredTxID(proof.BatchNumber, proof.BatchNumberFinal)
|
| 328 |
+
err = a.EthTxManager.Add(
|
| 329 |
+
ctx,
|
| 330 |
+
ethTxManagerOwner,
|
| 331 |
+
monitoredTxID,
|
| 332 |
+
sender,
|
| 333 |
+
to,
|
| 334 |
+
nil,
|
| 335 |
+
data,
|
| 336 |
+
a.cfg.GasOffset,
|
| 337 |
+
nil,
|
| 338 |
+
)
|
| 339 |
+
if err != nil {
|
| 340 |
+
mTxLogger := ethtxmanager.CreateLogger(ethTxManagerOwner, monitoredTxID, sender, to)
|
| 341 |
+
mTxLogger.Errorf("Error to add batch verification tx to eth tx manager: %v", err)
|
| 342 |
+
a.handleFailureToAddVerifyBatchToBeMonitored(ctx, proof)
|
| 343 |
+
|
| 344 |
+
return false
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
// process monitored batch verifications before starting a next cycle
|
| 348 |
+
a.EthTxManager.ProcessPendingMonitoredTxs(
|
| 349 |
+
ctx,
|
| 350 |
+
ethTxManagerOwner,
|
| 351 |
+
func(result ethtxmanager.MonitoredTxResult, dbTx pgx.Tx) {
|
| 352 |
+
a.handleMonitoredTxResult(result)
|
| 353 |
+
},
|
| 354 |
+
nil,
|
| 355 |
+
)
|
| 356 |
+
|
| 357 |
+
return true
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
func (a *Aggregator) settleWithAggLayer(
|
| 361 |
+
ctx context.Context,
|
| 362 |
+
proof *state.Proof,
|
| 363 |
+
inputs ethmanTypes.FinalProofInputs,
|
| 364 |
+
) (success bool) {
|
| 365 |
+
proofStrNo0x := strings.TrimPrefix(inputs.FinalProof.Proof, "0x")
|
| 366 |
+
proofBytes := common.Hex2Bytes(proofStrNo0x)
|
| 367 |
+
tx := tx.Tx{
|
| 368 |
+
LastVerifiedBatch: agglayerTypes.ArgUint64(proof.BatchNumber - 1),
|
| 369 |
+
NewVerifiedBatch: agglayerTypes.ArgUint64(proof.BatchNumberFinal),
|
| 370 |
+
ZKP: tx.ZKP{
|
| 371 |
+
NewStateRoot: common.BytesToHash(inputs.NewStateRoot),
|
| 372 |
+
NewLocalExitRoot: common.BytesToHash(inputs.NewLocalExitRoot),
|
| 373 |
+
Proof: agglayerTypes.ArgBytes(proofBytes),
|
| 374 |
+
},
|
| 375 |
+
RollupID: a.Ethman.GetRollupId(),
|
| 376 |
+
}
|
| 377 |
+
signedTx, err := tx.Sign(a.sequencerPrivateKey)
|
| 378 |
+
|
| 379 |
+
if err != nil {
|
| 380 |
+
log.Errorf("failed to sign tx: %v", err)
|
| 381 |
+
a.handleFailureToSendToAggLayer(ctx, proof)
|
| 382 |
+
|
| 383 |
+
return false
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
log.Debug("final proof signedTx: ", signedTx.Tx.ZKP.Proof.Hex())
|
| 387 |
+
txHash, err := a.AggLayerClient.SendTx(*signedTx)
|
| 388 |
+
if err != nil {
|
| 389 |
+
log.Errorf("failed to send tx to the interop: %v", err)
|
| 390 |
+
a.handleFailureToSendToAggLayer(ctx, proof)
|
| 391 |
+
|
| 392 |
+
return false
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
log.Infof("tx %s sent to agglayer, waiting to be mined", txHash.Hex())
|
| 396 |
+
log.Debugf("Timeout set to %f seconds", a.cfg.AggLayerTxTimeout.Duration.Seconds())
|
| 397 |
+
waitCtx, cancelFunc := context.WithDeadline(ctx, time.Now().Add(a.cfg.AggLayerTxTimeout.Duration))
|
| 398 |
+
defer cancelFunc()
|
| 399 |
+
if err := a.AggLayerClient.WaitTxToBeMined(txHash, waitCtx); err != nil {
|
| 400 |
+
log.Errorf("interop didn't mine the tx: %v", err)
|
| 401 |
+
a.handleFailureToSendToAggLayer(ctx, proof)
|
| 402 |
+
|
| 403 |
+
return false
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
// TODO: wait for synchronizer to catch up
|
| 407 |
+
return true
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
func (a *Aggregator) handleFailureToSendToAggLayer(ctx context.Context, proof *state.Proof) {
|
| 411 |
+
log := log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 412 |
+
proof.GeneratingSince = nil
|
| 413 |
+
|
| 414 |
+
err := a.State.UpdateGeneratedProof(ctx, proof, nil)
|
| 415 |
+
if err != nil {
|
| 416 |
+
log.Errorf("Failed updating proof state (false): %v", err)
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
a.endProofVerification()
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
func (a *Aggregator) handleFailureToAddVerifyBatchToBeMonitored(ctx context.Context, proof *state.Proof) {
|
| 423 |
+
log := log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 424 |
+
proof.GeneratingSince = nil
|
| 425 |
+
err := a.State.UpdateGeneratedProof(ctx, proof, nil)
|
| 426 |
+
if err != nil {
|
| 427 |
+
log.Errorf("Failed updating proof state (false): %v", err)
|
| 428 |
+
}
|
| 429 |
+
a.endProofVerification()
|
| 430 |
+
}
|
| 431 |
+
|
| 432 |
+
// buildFinalProof builds and return the final proof for an aggregated/batch proof.
|
| 433 |
+
func (a *Aggregator) buildFinalProof(ctx context.Context, prover proverInterface, proof *state.Proof) (*prover.FinalProof, error) {
|
| 434 |
+
log := log.WithFields(
|
| 435 |
+
"prover", prover.Name(),
|
| 436 |
+
"proverId", prover.ID(),
|
| 437 |
+
"proverAddr", prover.Addr(),
|
| 438 |
+
"recursiveProofId", *proof.ProofID,
|
| 439 |
+
"batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal),
|
| 440 |
+
)
|
| 441 |
+
log.Info("Generating final proof")
|
| 442 |
+
|
| 443 |
+
finalProofID, err := prover.FinalProof(proof.Proof, a.cfg.SenderAddress)
|
| 444 |
+
if err != nil {
|
| 445 |
+
return nil, fmt.Errorf("failed to get final proof id: %w", err)
|
| 446 |
+
}
|
| 447 |
+
proof.ProofID = finalProofID
|
| 448 |
+
|
| 449 |
+
log.Infof("Final proof ID for batches [%d-%d]: %s", proof.BatchNumber, proof.BatchNumberFinal, *proof.ProofID)
|
| 450 |
+
log = log.WithFields("finalProofId", finalProofID)
|
| 451 |
+
|
| 452 |
+
finalProof, err := prover.WaitFinalProof(ctx, *proof.ProofID)
|
| 453 |
+
if err != nil {
|
| 454 |
+
return nil, fmt.Errorf("failed to get final proof from prover: %w", err)
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
log.Info("Final proof generated")
|
| 458 |
+
|
| 459 |
+
// mock prover sanity check
|
| 460 |
+
if string(finalProof.Public.NewStateRoot) == mockedStateRoot && string(finalProof.Public.NewLocalExitRoot) == mockedLocalExitRoot {
|
| 461 |
+
// This local exit root and state root come from the mock
|
| 462 |
+
// prover, use the one captured by the executor instead
|
| 463 |
+
finalBatch, err := a.State.GetBatchByNumber(ctx, proof.BatchNumberFinal, nil)
|
| 464 |
+
if err != nil {
|
| 465 |
+
return nil, fmt.Errorf("failed to retrieve batch with number [%d]", proof.BatchNumberFinal)
|
| 466 |
+
}
|
| 467 |
+
log.Warnf("NewLocalExitRoot and NewStateRoot look like a mock values, using values from executor instead: LER: %v, SR: %v",
|
| 468 |
+
finalBatch.LocalExitRoot.TerminalString(), finalBatch.StateRoot.TerminalString())
|
| 469 |
+
finalProof.Public.NewStateRoot = finalBatch.StateRoot.Bytes()
|
| 470 |
+
finalProof.Public.NewLocalExitRoot = finalBatch.LocalExitRoot.Bytes()
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
+
return finalProof, nil
|
| 474 |
+
}
|
| 475 |
+
|
| 476 |
+
// tryBuildFinalProof checks if the provided proof is eligible to be used to
|
| 477 |
+
// build the final proof. If no proof is provided it looks for a previously
|
| 478 |
+
// generated proof. If the proof is eligible, then the final proof generation
|
| 479 |
+
// is triggered.
|
| 480 |
+
func (a *Aggregator) tryBuildFinalProof(ctx context.Context, prover proverInterface, proof *state.Proof) (bool, error) {
|
| 481 |
+
proverName := prover.Name()
|
| 482 |
+
proverID := prover.ID()
|
| 483 |
+
|
| 484 |
+
log := log.WithFields(
|
| 485 |
+
"prover", proverName,
|
| 486 |
+
"proverId", proverID,
|
| 487 |
+
"proverAddr", prover.Addr(),
|
| 488 |
+
)
|
| 489 |
+
log.Debug("tryBuildFinalProof start")
|
| 490 |
+
|
| 491 |
+
var err error
|
| 492 |
+
if !a.canVerifyProof() {
|
| 493 |
+
log.Debug("Time to verify proof not reached or proof verification in progress")
|
| 494 |
+
return false, nil
|
| 495 |
+
}
|
| 496 |
+
log.Debug("Send final proof time reached")
|
| 497 |
+
|
| 498 |
+
if err = a.waitForSynchronizerToSyncUp(ctx, nil); err != nil {
|
| 499 |
+
log.Warn("waiting for the synchronizer to sync up was canceled", err)
|
| 500 |
+
return false, err
|
| 501 |
+
}
|
| 502 |
+
|
| 503 |
+
var lastVerifiedBatchNum uint64
|
| 504 |
+
lastVerifiedBatch, err := a.State.GetLastVerifiedBatch(ctx, nil)
|
| 505 |
+
if err != nil && !errors.Is(err, state.ErrNotFound) {
|
| 506 |
+
return false, fmt.Errorf("failed to get last verified batch, %w", err)
|
| 507 |
+
}
|
| 508 |
+
if lastVerifiedBatch != nil {
|
| 509 |
+
lastVerifiedBatchNum = lastVerifiedBatch.BatchNumber
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
if proof == nil {
|
| 513 |
+
// we don't have a proof generating at the moment, check if we
|
| 514 |
+
// have a proof ready to verify
|
| 515 |
+
|
| 516 |
+
proof, err = a.getAndLockProofReadyToVerify(ctx, prover, lastVerifiedBatchNum)
|
| 517 |
+
if errors.Is(err, state.ErrNotFound) {
|
| 518 |
+
// nothing to verify, swallow the error
|
| 519 |
+
log.Debug("No proof ready to verify")
|
| 520 |
+
return false, nil
|
| 521 |
+
}
|
| 522 |
+
if err != nil {
|
| 523 |
+
return false, err
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
defer func() {
|
| 527 |
+
if err != nil {
|
| 528 |
+
// Set the generating state to false for the proof ("unlock" it)
|
| 529 |
+
proof.GeneratingSince = nil
|
| 530 |
+
err2 := a.State.UpdateGeneratedProof(a.ctx, proof, nil)
|
| 531 |
+
if err2 != nil {
|
| 532 |
+
log.Errorf("Failed to unlock proof: %v", err2)
|
| 533 |
}
|
| 534 |
}
|
| 535 |
+
}()
|
| 536 |
+
} else {
|
| 537 |
+
// we do have a proof generating at the moment, check if it is
|
| 538 |
+
// eligible to be verified
|
| 539 |
+
eligible, err := a.validateEligibleFinalProof(ctx, proof, lastVerifiedBatchNum)
|
| 540 |
+
if err != nil {
|
| 541 |
+
return false, fmt.Errorf("failed to validate eligible final proof, %w", err)
|
| 542 |
+
}
|
| 543 |
+
if !eligible {
|
| 544 |
+
return false, nil
|
| 545 |
+
}
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
log = log.WithFields(
|
| 549 |
+
"proofId", *proof.ProofID,
|
| 550 |
+
"batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal),
|
| 551 |
+
)
|
| 552 |
+
|
| 553 |
+
// at this point we have an eligible proof, build the final one using it
|
| 554 |
+
finalProof, err := a.buildFinalProof(ctx, prover, proof)
|
| 555 |
+
if err != nil {
|
| 556 |
+
err = fmt.Errorf("failed to build final proof, %w", err)
|
| 557 |
+
log.Error(FirstToUpper(err.Error()))
|
| 558 |
+
return false, err
|
| 559 |
+
}
|
| 560 |
+
|
| 561 |
+
msg := finalProofMsg{
|
| 562 |
+
proverName: proverName,
|
| 563 |
+
proverID: proverID,
|
| 564 |
+
recursiveProof: proof,
|
| 565 |
+
finalProof: finalProof,
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
select {
|
| 569 |
+
case <-a.ctx.Done():
|
| 570 |
+
return false, a.ctx.Err()
|
| 571 |
+
case a.finalProof <- msg:
|
| 572 |
+
}
|
| 573 |
+
|
| 574 |
+
log.Debug("tryBuildFinalProof end")
|
| 575 |
+
return true, nil
|
| 576 |
+
}
|
| 577 |
+
|
| 578 |
+
func (a *Aggregator) validateEligibleFinalProof(ctx context.Context, proof *state.Proof, lastVerifiedBatchNum uint64) (bool, error) {
|
| 579 |
+
batchNumberToVerify := lastVerifiedBatchNum + 1
|
| 580 |
+
|
| 581 |
+
if proof.BatchNumber != batchNumberToVerify {
|
| 582 |
+
if proof.BatchNumber < batchNumberToVerify && proof.BatchNumberFinal >= batchNumberToVerify {
|
| 583 |
+
// We have a proof that contains some batches below the last batch verified, anyway can be eligible as final proof
|
| 584 |
+
log.Warnf("Proof %d-%d contains some batches lower than last batch verified %d. Check anyway if it is eligible", proof.BatchNumber, proof.BatchNumberFinal, lastVerifiedBatchNum)
|
| 585 |
+
} else if proof.BatchNumberFinal < batchNumberToVerify {
|
| 586 |
+
// We have a proof that contains batches below that the last batch verified, we need to delete this proof
|
| 587 |
+
log.Warnf("Proof %d-%d lower than next batch to verify %d. Deleting it", proof.BatchNumber, proof.BatchNumberFinal, batchNumberToVerify)
|
| 588 |
+
err := a.State.DeleteGeneratedProofs(ctx, proof.BatchNumber, proof.BatchNumberFinal, nil)
|
| 589 |
+
if err != nil {
|
| 590 |
+
return false, fmt.Errorf("failed to delete discarded proof, err: %w", err)
|
| 591 |
+
}
|
| 592 |
+
return false, nil
|
| 593 |
+
} else {
|
| 594 |
+
log.Debugf("Proof batch number %d is not the following to last verfied batch number %d", proof.BatchNumber, lastVerifiedBatchNum)
|
| 595 |
+
return false, nil
|
| 596 |
}
|
| 597 |
}
|
| 598 |
+
|
| 599 |
+
bComplete, err := a.State.CheckProofContainsCompleteSequences(ctx, proof, nil)
|
| 600 |
+
if err != nil {
|
| 601 |
+
return false, fmt.Errorf("failed to check if proof contains complete sequences, %w", err)
|
| 602 |
+
}
|
| 603 |
+
if !bComplete {
|
| 604 |
+
log.Infof("Recursive proof %d-%d not eligible to be verified: not containing complete sequences", proof.BatchNumber, proof.BatchNumberFinal)
|
| 605 |
+
return false, nil
|
| 606 |
+
}
|
| 607 |
+
return true, nil
|
| 608 |
+
}
|
| 609 |
+
|
| 610 |
+
func (a *Aggregator) getAndLockProofReadyToVerify(ctx context.Context, prover proverInterface, lastVerifiedBatchNum uint64) (*state.Proof, error) {
|
| 611 |
+
a.StateDBMutex.Lock()
|
| 612 |
+
defer a.StateDBMutex.Unlock()
|
| 613 |
+
|
| 614 |
+
// Get proof ready to be verified
|
| 615 |
+
proofToVerify, err := a.State.GetProofReadyToVerify(ctx, lastVerifiedBatchNum, nil)
|
| 616 |
+
if err != nil {
|
| 617 |
+
return nil, err
|
| 618 |
+
}
|
| 619 |
+
|
| 620 |
+
now := time.Now().Round(time.Microsecond)
|
| 621 |
+
proofToVerify.GeneratingSince = &now
|
| 622 |
+
|
| 623 |
+
err = a.State.UpdateGeneratedProof(ctx, proofToVerify, nil)
|
| 624 |
+
if err != nil {
|
| 625 |
+
return nil, err
|
| 626 |
+
}
|
| 627 |
+
|
| 628 |
+
return proofToVerify, nil
|
| 629 |
+
}
|
| 630 |
+
|
| 631 |
+
func (a *Aggregator) unlockProofsToAggregate(ctx context.Context, proof1 *state.Proof, proof2 *state.Proof) error {
|
| 632 |
+
// Release proofs from generating state in a single transaction
|
| 633 |
+
dbTx, err := a.State.BeginStateTransaction(ctx)
|
| 634 |
+
if err != nil {
|
| 635 |
+
log.Warnf("Failed to begin transaction to release proof aggregation state, err: %v", err)
|
| 636 |
+
return err
|
| 637 |
+
}
|
| 638 |
+
|
| 639 |
+
proof1.GeneratingSince = nil
|
| 640 |
+
err = a.State.UpdateGeneratedProof(ctx, proof1, dbTx)
|
| 641 |
+
if err == nil {
|
| 642 |
+
proof2.GeneratingSince = nil
|
| 643 |
+
err = a.State.UpdateGeneratedProof(ctx, proof2, dbTx)
|
| 644 |
+
}
|
| 645 |
+
|
| 646 |
+
if err != nil {
|
| 647 |
+
if err := dbTx.Rollback(ctx); err != nil {
|
| 648 |
+
err := fmt.Errorf("failed to rollback proof aggregation state: %w", err)
|
| 649 |
+
log.Error(FirstToUpper(err.Error()))
|
| 650 |
+
return err
|
| 651 |
+
}
|
| 652 |
+
return fmt.Errorf("failed to release proof aggregation state: %w", err)
|
| 653 |
+
}
|
| 654 |
+
|
| 655 |
+
err = dbTx.Commit(ctx)
|
| 656 |
+
if err != nil {
|
| 657 |
+
return fmt.Errorf("failed to release proof aggregation state %w", err)
|
| 658 |
+
}
|
| 659 |
+
|
| 660 |
+
return nil
|
| 661 |
+
}
|
| 662 |
+
|
| 663 |
+
func (a *Aggregator) getAndLockProofsToAggregate(ctx context.Context, prover proverInterface) (*state.Proof, *state.Proof, error) {
|
| 664 |
+
log := log.WithFields(
|
| 665 |
+
"prover", prover.Name(),
|
| 666 |
+
"proverId", prover.ID(),
|
| 667 |
+
"proverAddr", prover.Addr(),
|
| 668 |
+
)
|
| 669 |
+
|
| 670 |
+
a.StateDBMutex.Lock()
|
| 671 |
+
defer a.StateDBMutex.Unlock()
|
| 672 |
+
|
| 673 |
+
proof1, proof2, err := a.State.GetProofsToAggregate(ctx, nil)
|
| 674 |
+
if err != nil {
|
| 675 |
+
return nil, nil, err
|
| 676 |
+
}
|
| 677 |
+
|
| 678 |
+
// Set proofs in generating state in a single transaction
|
| 679 |
+
dbTx, err := a.State.BeginStateTransaction(ctx)
|
| 680 |
+
if err != nil {
|
| 681 |
+
log.Errorf("Failed to begin transaction to set proof aggregation state, err: %v", err)
|
| 682 |
+
return nil, nil, err
|
| 683 |
+
}
|
| 684 |
+
|
| 685 |
+
now := time.Now().Round(time.Microsecond)
|
| 686 |
+
proof1.GeneratingSince = &now
|
| 687 |
+
err = a.State.UpdateGeneratedProof(ctx, proof1, dbTx)
|
| 688 |
+
if err == nil {
|
| 689 |
+
proof2.GeneratingSince = &now
|
| 690 |
+
err = a.State.UpdateGeneratedProof(ctx, proof2, dbTx)
|
| 691 |
+
}
|
| 692 |
+
|
| 693 |
+
if err != nil {
|
| 694 |
+
if err := dbTx.Rollback(ctx); err != nil {
|
| 695 |
+
err := fmt.Errorf("failed to rollback proof aggregation state %w", err)
|
| 696 |
+
log.Error(FirstToUpper(err.Error()))
|
| 697 |
+
return nil, nil, err
|
| 698 |
+
}
|
| 699 |
+
return nil, nil, fmt.Errorf("failed to set proof aggregation state %w", err)
|
| 700 |
+
}
|
| 701 |
+
|
| 702 |
+
err = dbTx.Commit(ctx)
|
| 703 |
+
if err != nil {
|
| 704 |
+
return nil, nil, fmt.Errorf("failed to set proof aggregation state %w", err)
|
| 705 |
+
}
|
| 706 |
+
|
| 707 |
+
return proof1, proof2, nil
|
| 708 |
+
}
|
| 709 |
+
|
| 710 |
+
func (a *Aggregator) tryAggregateProofs(ctx context.Context, prover proverInterface) (bool, error) {
|
| 711 |
+
proverName := prover.Name()
|
| 712 |
+
proverID := prover.ID()
|
| 713 |
+
|
| 714 |
+
log := log.WithFields(
|
| 715 |
+
"prover", proverName,
|
| 716 |
+
"proverId", proverID,
|
| 717 |
+
"proverAddr", prover.Addr(),
|
| 718 |
+
)
|
| 719 |
+
log.Debug("tryAggregateProofs start")
|
| 720 |
+
|
| 721 |
+
proof1, proof2, err0 := a.getAndLockProofsToAggregate(ctx, prover)
|
| 722 |
+
if errors.Is(err0, state.ErrNotFound) {
|
| 723 |
+
// nothing to aggregate, swallow the error
|
| 724 |
+
log.Debug("Nothing to aggregate")
|
| 725 |
+
return false, nil
|
| 726 |
+
}
|
| 727 |
+
if err0 != nil {
|
| 728 |
+
return false, err0
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
var (
|
| 732 |
+
aggrProofID *string
|
| 733 |
+
err error
|
| 734 |
+
)
|
| 735 |
+
|
| 736 |
+
defer func() {
|
| 737 |
+
if err != nil {
|
| 738 |
+
err2 := a.unlockProofsToAggregate(a.ctx, proof1, proof2)
|
| 739 |
+
if err2 != nil {
|
| 740 |
+
log.Errorf("Failed to release aggregated proofs, err: %v", err2)
|
| 741 |
+
}
|
| 742 |
+
}
|
| 743 |
+
log.Debug("tryAggregateProofs end")
|
| 744 |
+
}()
|
| 745 |
+
|
| 746 |
+
log.Infof("Aggregating proofs: %d-%d and %d-%d", proof1.BatchNumber, proof1.BatchNumberFinal, proof2.BatchNumber, proof2.BatchNumberFinal)
|
| 747 |
+
|
| 748 |
+
batches := fmt.Sprintf("%d-%d", proof1.BatchNumber, proof2.BatchNumberFinal)
|
| 749 |
+
log = log.WithFields("batches", batches)
|
| 750 |
+
|
| 751 |
+
inputProver := map[string]interface{}{
|
| 752 |
+
"recursive_proof_1": proof1.Proof,
|
| 753 |
+
"recursive_proof_2": proof2.Proof,
|
| 754 |
+
}
|
| 755 |
+
b, err := json.Marshal(inputProver)
|
| 756 |
+
if err != nil {
|
| 757 |
+
err = fmt.Errorf("failed to serialize input prover, %w", err)
|
| 758 |
+
log.Error(FirstToUpper(err.Error()))
|
| 759 |
+
return false, err
|
| 760 |
+
}
|
| 761 |
+
|
| 762 |
+
proof := &state.Proof{
|
| 763 |
+
BatchNumber: proof1.BatchNumber,
|
| 764 |
+
BatchNumberFinal: proof2.BatchNumberFinal,
|
| 765 |
+
Prover: &proverName,
|
| 766 |
+
ProverID: &proverID,
|
| 767 |
+
InputProver: string(b),
|
| 768 |
+
}
|
| 769 |
+
|
| 770 |
+
aggrProofID, err = prover.AggregatedProof(proof1.Proof, proof2.Proof)
|
| 771 |
+
if err != nil {
|
| 772 |
+
err = fmt.Errorf("failed to get aggregated proof id, %w", err)
|
| 773 |
+
log.Error(FirstToUpper(err.Error()))
|
| 774 |
+
return false, err
|
| 775 |
+
}
|
| 776 |
+
|
| 777 |
+
proof.ProofID = aggrProofID
|
| 778 |
+
|
| 779 |
+
log.Infof("Proof ID for aggregated proof: %v", *proof.ProofID)
|
| 780 |
+
log = log.WithFields("proofId", *proof.ProofID)
|
| 781 |
+
|
| 782 |
+
recursiveProof, err := prover.WaitRecursiveProof(ctx, *proof.ProofID)
|
| 783 |
+
if err != nil {
|
| 784 |
+
err = fmt.Errorf("failed to get aggregated proof from prover, %w", err)
|
| 785 |
+
log.Error(FirstToUpper(err.Error()))
|
| 786 |
+
return false, err
|
| 787 |
+
}
|
| 788 |
+
|
| 789 |
+
log.Info("Aggregated proof generated")
|
| 790 |
+
|
| 791 |
+
proof.Proof = recursiveProof
|
| 792 |
+
|
| 793 |
+
// update the state by removing the 2 aggregated proofs and storing the
|
| 794 |
+
// newly generated recursive proof
|
| 795 |
+
dbTx, err := a.State.BeginStateTransaction(ctx)
|
| 796 |
+
if err != nil {
|
| 797 |
+
err = fmt.Errorf("failed to begin transaction to update proof aggregation state, %w", err)
|
| 798 |
+
log.Error(FirstToUpper(err.Error()))
|
| 799 |
+
return false, err
|
| 800 |
+
}
|
| 801 |
+
|
| 802 |
+
err = a.State.DeleteGeneratedProofs(ctx, proof1.BatchNumber, proof2.BatchNumberFinal, dbTx)
|
| 803 |
+
if err != nil {
|
| 804 |
+
if err := dbTx.Rollback(ctx); err != nil {
|
| 805 |
+
err := fmt.Errorf("failed to rollback proof aggregation state, %w", err)
|
| 806 |
+
log.Error(FirstToUpper(err.Error()))
|
| 807 |
+
return false, err
|
| 808 |
+
}
|
| 809 |
+
err = fmt.Errorf("failed to delete previously aggregated proofs, %w", err)
|
| 810 |
+
log.Error(FirstToUpper(err.Error()))
|
| 811 |
+
return false, err
|
| 812 |
+
}
|
| 813 |
+
|
| 814 |
+
now := time.Now().Round(time.Microsecond)
|
| 815 |
+
proof.GeneratingSince = &now
|
| 816 |
+
|
| 817 |
+
err = a.State.AddGeneratedProof(ctx, proof, dbTx)
|
| 818 |
+
if err != nil {
|
| 819 |
+
if err := dbTx.Rollback(ctx); err != nil {
|
| 820 |
+
err := fmt.Errorf("failed to rollback proof aggregation state, %w", err)
|
| 821 |
+
log.Error(FirstToUpper(err.Error()))
|
| 822 |
+
return false, err
|
| 823 |
+
}
|
| 824 |
+
err = fmt.Errorf("failed to store the recursive proof, %w", err)
|
| 825 |
+
log.Error(FirstToUpper(err.Error()))
|
| 826 |
+
return false, err
|
| 827 |
+
}
|
| 828 |
+
|
| 829 |
+
err = dbTx.Commit(ctx)
|
| 830 |
+
if err != nil {
|
| 831 |
+
err = fmt.Errorf("failed to store the recursive proof, %w", err)
|
| 832 |
+
log.Error(FirstToUpper(err.Error()))
|
| 833 |
+
return false, err
|
| 834 |
+
}
|
| 835 |
+
|
| 836 |
+
// NOTE(pg): the defer func is useless from now on, use a different variable
|
| 837 |
+
// name for errors (or shadow err in inner scopes) to not trigger it.
|
| 838 |
+
|
| 839 |
+
// state is up to date, check if we can send the final proof using the
|
| 840 |
+
// one just crafted.
|
| 841 |
+
finalProofBuilt, finalProofErr := a.tryBuildFinalProof(ctx, prover, proof)
|
| 842 |
+
if finalProofErr != nil {
|
| 843 |
+
// just log the error and continue to handle the aggregated proof
|
| 844 |
+
log.Errorf("Failed trying to check if recursive proof can be verified: %v", finalProofErr)
|
| 845 |
+
}
|
| 846 |
+
|
| 847 |
+
// NOTE(pg): prover is done, use a.ctx from now on
|
| 848 |
+
|
| 849 |
+
if !finalProofBuilt {
|
| 850 |
+
proof.GeneratingSince = nil
|
| 851 |
+
|
| 852 |
+
// final proof has not been generated, update the recursive proof
|
| 853 |
+
err := a.State.UpdateGeneratedProof(a.ctx, proof, nil)
|
| 854 |
+
if err != nil {
|
| 855 |
+
err = fmt.Errorf("failed to store batch proof result, %w", err)
|
| 856 |
+
log.Error(FirstToUpper(err.Error()))
|
| 857 |
+
return false, err
|
| 858 |
+
}
|
| 859 |
+
}
|
| 860 |
+
|
| 861 |
+
return true, nil
|
| 862 |
+
}
|
| 863 |
+
|
| 864 |
+
func (a *Aggregator) getAndLockBatchToProve(ctx context.Context, prover proverInterface) (*state.Batch, *state.Proof, error) {
|
| 865 |
+
proverID := prover.ID()
|
| 866 |
+
proverName := prover.Name()
|
| 867 |
+
|
| 868 |
+
log := log.WithFields(
|
| 869 |
+
"prover", proverName,
|
| 870 |
+
"proverId", proverID,
|
| 871 |
+
"proverAddr", prover.Addr(),
|
| 872 |
+
)
|
| 873 |
+
|
| 874 |
+
a.StateDBMutex.Lock()
|
| 875 |
+
defer a.StateDBMutex.Unlock()
|
| 876 |
+
|
| 877 |
+
lastVerifiedBatch, err := a.State.GetLastVerifiedBatch(ctx, nil)
|
| 878 |
+
if err != nil {
|
| 879 |
+
return nil, nil, err
|
| 880 |
+
}
|
| 881 |
+
|
| 882 |
+
// Get header of the last L1 block
|
| 883 |
+
lastL1BlockHeader, err := a.Ethman.GetLatestBlockHeader(ctx)
|
| 884 |
+
if err != nil {
|
| 885 |
+
log.Errorf("Failed to get last L1 block header, err: %v", err)
|
| 886 |
+
return nil, nil, err
|
| 887 |
+
}
|
| 888 |
+
lastL1BlockNumber := lastL1BlockHeader.Number.Uint64()
|
| 889 |
+
|
| 890 |
+
// Calculate max L1 block number for getting next virtual batch to prove
|
| 891 |
+
maxL1BlockNumber := uint64(0)
|
| 892 |
+
if a.cfg.BatchProofL1BlockConfirmations <= lastL1BlockNumber {
|
| 893 |
+
maxL1BlockNumber = lastL1BlockNumber - a.cfg.BatchProofL1BlockConfirmations
|
| 894 |
+
}
|
| 895 |
+
log.Debugf("Max L1 block number for getting next virtual batch to prove: %d", maxL1BlockNumber)
|
| 896 |
+
|
| 897 |
+
// Get virtual batch pending to generate proof
|
| 898 |
+
batchToVerify, err := a.State.GetVirtualBatchToProve(ctx, lastVerifiedBatch.BatchNumber, maxL1BlockNumber, nil)
|
| 899 |
+
if err != nil {
|
| 900 |
+
return nil, nil, err
|
| 901 |
+
}
|
| 902 |
+
|
| 903 |
+
log.Infof("Found virtual batch %d pending to generate proof", batchToVerify.BatchNumber)
|
| 904 |
+
log = log.WithFields("batch", batchToVerify.BatchNumber)
|
| 905 |
+
|
| 906 |
+
log.Info("Checking profitability to aggregate batch")
|
| 907 |
+
|
| 908 |
+
// pass pol collateral as zero here, bcs in smart contract fee for aggregator is not defined yet
|
| 909 |
+
isProfitable, err := a.ProfitabilityChecker.IsProfitable(ctx, big.NewInt(0))
|
| 910 |
+
if err != nil {
|
| 911 |
+
log.Errorf("Failed to check aggregator profitability, err: %v", err)
|
| 912 |
+
return nil, nil, err
|
| 913 |
+
}
|
| 914 |
+
|
| 915 |
+
if !isProfitable {
|
| 916 |
+
log.Infof("Batch is not profitable, pol collateral %d", big.NewInt(0))
|
| 917 |
+
return nil, nil, err
|
| 918 |
+
}
|
| 919 |
+
|
| 920 |
+
now := time.Now().Round(time.Microsecond)
|
| 921 |
+
proof := &state.Proof{
|
| 922 |
+
BatchNumber: batchToVerify.BatchNumber,
|
| 923 |
+
BatchNumberFinal: batchToVerify.BatchNumber,
|
| 924 |
+
Prover: &proverName,
|
| 925 |
+
ProverID: &proverID,
|
| 926 |
+
GeneratingSince: &now,
|
| 927 |
+
}
|
| 928 |
+
|
| 929 |
+
// Avoid other prover to process the same batch
|
| 930 |
+
err = a.State.AddGeneratedProof(ctx, proof, nil)
|
| 931 |
+
if err != nil {
|
| 932 |
+
log.Errorf("Failed to add batch proof, err: %v", err)
|
| 933 |
+
return nil, nil, err
|
| 934 |
+
}
|
| 935 |
+
|
| 936 |
+
return batchToVerify, proof, nil
|
| 937 |
+
}
|
| 938 |
+
|
| 939 |
+
func (a *Aggregator) tryGenerateBatchProof(ctx context.Context, prover proverInterface) (bool, error) {
|
| 940 |
+
log := log.WithFields(
|
| 941 |
+
"prover", prover.Name(),
|
| 942 |
+
"proverId", prover.ID(),
|
| 943 |
+
"proverAddr", prover.Addr(),
|
| 944 |
+
)
|
| 945 |
+
log.Debug("tryGenerateBatchProof start")
|
| 946 |
+
|
| 947 |
+
batchToProve, proof, err0 := a.getAndLockBatchToProve(ctx, prover)
|
| 948 |
+
if errors.Is(err0, state.ErrNotFound) {
|
| 949 |
+
// nothing to proof, swallow the error
|
| 950 |
+
log.Debug("Nothing to generate proof")
|
| 951 |
+
return false, nil
|
| 952 |
+
}
|
| 953 |
+
if err0 != nil {
|
| 954 |
+
return false, err0
|
| 955 |
+
}
|
| 956 |
+
|
| 957 |
+
log = log.WithFields("batch", batchToProve.BatchNumber)
|
| 958 |
+
|
| 959 |
+
var (
|
| 960 |
+
genProofID *string
|
| 961 |
+
err error
|
| 962 |
+
)
|
| 963 |
+
|
| 964 |
+
defer func() {
|
| 965 |
+
if err != nil {
|
| 966 |
+
err2 := a.State.DeleteGeneratedProofs(a.ctx, proof.BatchNumber, proof.BatchNumberFinal, nil)
|
| 967 |
+
if err2 != nil {
|
| 968 |
+
log.Errorf("Failed to delete proof in progress, err: %v", err2)
|
| 969 |
+
}
|
| 970 |
+
}
|
| 971 |
+
log.Debug("tryGenerateBatchProof end")
|
| 972 |
+
}()
|
| 973 |
+
|
| 974 |
+
log.Info("Generating proof from batch")
|
| 975 |
+
|
| 976 |
+
log.Infof("Sending zki + batch to the prover, batchNumber [%d]", batchToProve.BatchNumber)
|
| 977 |
+
inputProver, err := a.buildInputProver(ctx, batchToProve)
|
| 978 |
+
if err != nil {
|
| 979 |
+
err = fmt.Errorf("failed to build input prover, %w", err)
|
| 980 |
+
log.Error(FirstToUpper(err.Error()))
|
| 981 |
+
return false, err
|
| 982 |
+
}
|
| 983 |
+
|
| 984 |
+
b, err := json.Marshal(inputProver)
|
| 985 |
+
if err != nil {
|
| 986 |
+
err = fmt.Errorf("failed to serialize input prover, %w", err)
|
| 987 |
+
log.Error(FirstToUpper(err.Error()))
|
| 988 |
+
return false, err
|
| 989 |
+
}
|
| 990 |
+
|
| 991 |
+
proof.InputProver = string(b)
|
| 992 |
+
|
| 993 |
+
log.Infof("Sending a batch to the prover. OldStateRoot [%#x], OldBatchNum [%d]",
|
| 994 |
+
inputProver.PublicInputs.OldStateRoot, inputProver.PublicInputs.OldBatchNum)
|
| 995 |
+
|
| 996 |
+
genProofID, err = prover.BatchProof(inputProver)
|
| 997 |
+
if err != nil {
|
| 998 |
+
err = fmt.Errorf("failed to get batch proof id, %w", err)
|
| 999 |
+
log.Error(FirstToUpper(err.Error()))
|
| 1000 |
+
return false, err
|
| 1001 |
+
}
|
| 1002 |
+
|
| 1003 |
+
proof.ProofID = genProofID
|
| 1004 |
+
|
| 1005 |
+
log.Infof("Proof ID %v", *proof.ProofID)
|
| 1006 |
+
log = log.WithFields("proofId", *proof.ProofID)
|
| 1007 |
+
|
| 1008 |
+
resGetProof, err := prover.WaitRecursiveProof(ctx, *proof.ProofID)
|
| 1009 |
+
if err != nil {
|
| 1010 |
+
err = fmt.Errorf("failed to get proof from prover, %w", err)
|
| 1011 |
+
log.Error(FirstToUpper(err.Error()))
|
| 1012 |
+
return false, err
|
| 1013 |
+
}
|
| 1014 |
+
|
| 1015 |
+
log.Info("Batch proof generated")
|
| 1016 |
+
|
| 1017 |
+
proof.Proof = resGetProof
|
| 1018 |
+
|
| 1019 |
+
// NOTE(pg): the defer func is useless from now on, use a different variable
|
| 1020 |
+
// name for errors (or shadow err in inner scopes) to not trigger it.
|
| 1021 |
+
|
| 1022 |
+
finalProofBuilt, finalProofErr := a.tryBuildFinalProof(ctx, prover, proof)
|
| 1023 |
+
if finalProofErr != nil {
|
| 1024 |
+
// just log the error and continue to handle the generated proof
|
| 1025 |
+
log.Errorf("Error trying to build final proof: %v", finalProofErr)
|
| 1026 |
+
}
|
| 1027 |
+
|
| 1028 |
+
// NOTE(pg): prover is done, use a.ctx from now on
|
| 1029 |
+
|
| 1030 |
+
if !finalProofBuilt {
|
| 1031 |
+
proof.GeneratingSince = nil
|
| 1032 |
+
|
| 1033 |
+
// final proof has not been generated, update the batch proof
|
| 1034 |
+
err := a.State.UpdateGeneratedProof(a.ctx, proof, nil)
|
| 1035 |
+
if err != nil {
|
| 1036 |
+
err = fmt.Errorf("failed to store batch proof result, %w", err)
|
| 1037 |
+
log.Error(FirstToUpper(err.Error()))
|
| 1038 |
+
return false, err
|
| 1039 |
+
}
|
| 1040 |
+
}
|
| 1041 |
+
|
| 1042 |
+
return true, nil
|
| 1043 |
}
|
| 1044 |
|
| 1045 |
// canVerifyProof returns true if we have reached the timeout to verify a proof
|
|
|
|
| 1073 |
|
| 1074 |
// isSynced checks if the state is synchronized with L1. If a batch number is
|
| 1075 |
// provided, it makes sure that the state is synced with that batch.
|
| 1076 |
+
func (a *Aggregator) isSynced(ctx context.Context, batchNum *uint64) (bool, error) {
|
| 1077 |
// get latest verified batch as seen by the synchronizer
|
| 1078 |
lastVerifiedBatch, err := a.State.GetLastVerifiedBatch(ctx, nil)
|
| 1079 |
if err == state.ErrNotFound {
|
| 1080 |
+
return false, nil
|
| 1081 |
}
|
| 1082 |
if err != nil {
|
| 1083 |
log.Warnf("Failed to get last consolidated batch: %v", err)
|
| 1084 |
+
return false, err
|
| 1085 |
}
|
| 1086 |
|
| 1087 |
if lastVerifiedBatch == nil {
|
| 1088 |
+
return false, nil
|
| 1089 |
}
|
| 1090 |
|
| 1091 |
if batchNum != nil && lastVerifiedBatch.BatchNumber < *batchNum {
|
| 1092 |
log.Infof("Waiting for the state to be synced, lastVerifiedBatchNum: %d, waiting for batch: %d", lastVerifiedBatch.BatchNumber, batchNum)
|
| 1093 |
+
return false, nil
|
| 1094 |
}
|
| 1095 |
|
| 1096 |
// latest verified batch in L1
|
| 1097 |
lastVerifiedEthBatchNum, err := a.Ethman.GetLatestVerifiedBatchNum()
|
| 1098 |
if err != nil {
|
| 1099 |
log.Warnf("Failed to get last eth batch, err: %v", err)
|
| 1100 |
+
return false, err
|
| 1101 |
}
|
| 1102 |
|
| 1103 |
// check if L2 is synced with L1
|
| 1104 |
if lastVerifiedBatch.BatchNumber < lastVerifiedEthBatchNum {
|
| 1105 |
log.Infof("Waiting for the state to be synced, lastVerifiedBatchNum: %d, lastVerifiedEthBatchNum: %d, waiting for batch",
|
| 1106 |
lastVerifiedBatch.BatchNumber, lastVerifiedEthBatchNum)
|
| 1107 |
+
return false, nil
|
| 1108 |
}
|
| 1109 |
|
| 1110 |
+
return true, nil
|
| 1111 |
}
|
| 1112 |
|
| 1113 |
func (a *Aggregator) buildInputProver(ctx context.Context, batchToVerify *state.Batch) (*prover.InputProver, error) {
|
|
|
|
| 1171 |
}
|
| 1172 |
if l1InfoRoot != nil && *l1InfoRoot != calculatedL1InfoRoot {
|
| 1173 |
for i, l := range aLeaves {
|
| 1174 |
+
log.Info("AllLeaves[%d]: %s", i, common.Bytes2Hex(l[:]))
|
| 1175 |
}
|
| 1176 |
for i, s := range smtProof {
|
| 1177 |
+
log.Info("smtProof[%d]: %s", i, common.Bytes2Hex(s[:]))
|
| 1178 |
}
|
| 1179 |
return nil, fmt.Errorf("error: l1InfoRoot mismatch. L1InfoRoot: %s, calculatedL1InfoRoot: %s. l1InfoTreeIndex: %d", l1InfoRoot.String(), calculatedL1InfoRoot.String(), l2blockRaw.IndexL1InfoTree)
|
| 1180 |
}
|
|
|
|
| 1301 |
|
| 1302 |
// wait for the synchronizer to catch up the verified batches
|
| 1303 |
log.Debug("A final proof has been sent, waiting for the network to be synced")
|
| 1304 |
+
if err := a.waitForSynchronizerToSyncUp(a.ctx, &proofBatchNumberFinal); err != nil {
|
| 1305 |
+
log.Warn("waiting for the synchronizer to sync up was canceled", err)
|
| 1306 |
+
return
|
| 1307 |
}
|
| 1308 |
|
| 1309 |
// network is synced with the final proof, we can safely delete all recursive
|
| 1310 |
// proofs up to the last synced batch
|
| 1311 |
+
err = a.State.CleanupGeneratedProofs(a.ctx, proofBatchNumberFinal, nil)
|
| 1312 |
if err != nil {
|
| 1313 |
log.Errorf("Failed to store proof aggregation result: %v", err)
|
| 1314 |
}
|
| 1315 |
}
|
| 1316 |
|
| 1317 |
+
func (a *Aggregator) waitForSynchronizerToSyncUp(ctx context.Context, batchNum *uint64) error {
|
| 1318 |
+
for {
|
| 1319 |
+
log.Info("waiting for the synchronizer to sync...")
|
| 1320 |
+
synced, err := a.isSynced(ctx, batchNum)
|
| 1321 |
+
if err != nil && errors.Is(err, context.Canceled) {
|
| 1322 |
+
// if context is canceled, stop the loop, since it will never
|
| 1323 |
+
// be able to execute properly and break in this case, and we will be stuck in it forever
|
| 1324 |
+
return err
|
| 1325 |
+
}
|
| 1326 |
+
|
| 1327 |
+
if synced {
|
| 1328 |
+
return nil
|
| 1329 |
+
}
|
| 1330 |
+
|
| 1331 |
+
time.Sleep(a.cfg.RetryTime.Duration)
|
| 1332 |
+
}
|
| 1333 |
+
}
|
| 1334 |
+
|
| 1335 |
func buildMonitoredTxID(batchNumber, batchNumberFinal uint64) string {
|
| 1336 |
return fmt.Sprintf(monitoredIDFormat, batchNumber, batchNumberFinal)
|
| 1337 |
}
|
|
|
|
| 1342 |
case <-a.ctx.Done():
|
| 1343 |
return
|
| 1344 |
case <-time.After(a.TimeCleanupLockedProofs.Duration):
|
| 1345 |
+
n, err := a.State.CleanupLockedProofs(a.ctx, a.cfg.GeneratingProofCleanupThreshold, nil)
|
| 1346 |
if err != nil {
|
| 1347 |
log.Errorf("Failed to cleanup locked proofs: %v", err)
|
| 1348 |
}
|
|
@@ -89,7 +89,7 @@
|
|
| 89 |
m.etherman.On("BuildTrustedVerifyBatchesTxData", batchNum-1, batchNumFinal, &expectedInputs, common.HexToAddress(cfg.SenderAddress)).Run(func(args mock.Arguments) {
|
| 90 |
assert.True(a.verifyingProof)
|
| 91 |
}).Return(nil, nil, errBanana).Once()
|
| 92 |
-
m.stateMock.On("
|
| 93 |
// test is done, stop the sendFinalProof method
|
| 94 |
a.exit()
|
| 95 |
}).Return(nil).Once()
|
|
@@ -99,7 +99,7 @@
|
|
| 99 |
},
|
| 100 |
},
|
| 101 |
{
|
| 102 |
-
name: "
|
| 103 |
setup: func(m mox, a *Aggregator) {
|
| 104 |
m.stateMock.On("GetBatchByNumber", mock.Anything, batchNumFinal, nil).Run(func(args mock.Arguments) {
|
| 105 |
assert.True(a.verifyingProof)
|
|
@@ -112,7 +112,7 @@
|
|
| 112 |
m.etherman.On("BuildTrustedVerifyBatchesTxData", batchNum-1, batchNumFinal, &expectedInputs, common.HexToAddress(cfg.SenderAddress)).Run(func(args mock.Arguments) {
|
| 113 |
assert.True(a.verifyingProof)
|
| 114 |
}).Return(nil, nil, errBanana).Once()
|
| 115 |
-
m.stateMock.On("
|
| 116 |
// test is done, stop the sendFinalProof method
|
| 117 |
a.exit()
|
| 118 |
}).Return(errBanana).Once()
|
|
@@ -137,7 +137,7 @@
|
|
| 137 |
}).Return(&to, data, nil).Once()
|
| 138 |
monitoredTxID := buildMonitoredTxID(batchNum, batchNumFinal)
|
| 139 |
m.ethTxManager.On("Add", mock.Anything, ethTxManagerOwner, monitoredTxID, from, &to, value, data, cfg.GasOffset, nil).Return(errBanana).Once()
|
| 140 |
-
m.stateMock.On("
|
| 141 |
// test is done, stop the sendFinalProof method
|
| 142 |
a.exit()
|
| 143 |
}).Return(nil).Once()
|
|
@@ -175,7 +175,7 @@
|
|
| 175 |
}
|
| 176 |
m.stateMock.On("GetLastVerifiedBatch", mock.Anything, nil).Return(&verifiedBatch, nil).Once()
|
| 177 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(batchNumFinal, nil).Once()
|
| 178 |
-
m.stateMock.On("
|
| 179 |
// test is done, stop the sendFinalProof method
|
| 180 |
a.exit()
|
| 181 |
}).Return(nil).Once()
|
|
@@ -191,7 +191,7 @@
|
|
| 191 |
stateMock := mocks.NewStateMock(t)
|
| 192 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 193 |
etherman := mocks.NewEtherman(t)
|
| 194 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 195 |
require.NoError(err)
|
| 196 |
a.ctx, a.exit = context.WithCancel(context.Background())
|
| 197 |
m := mox{
|
|
@@ -251,12 +251,12 @@
|
|
| 251 |
asserts func(bool, *Aggregator, error)
|
| 252 |
}{
|
| 253 |
{
|
| 254 |
-
name: "
|
| 255 |
setup: func(m mox, a *Aggregator) {
|
| 256 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 257 |
m.proverMock.On("ID").Return(proverID).Twice()
|
| 258 |
m.proverMock.On("Addr").Return("addr")
|
| 259 |
-
m.stateMock.On("
|
| 260 |
},
|
| 261 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 262 |
assert.False(result)
|
|
@@ -264,12 +264,12 @@
|
|
| 264 |
},
|
| 265 |
},
|
| 266 |
{
|
| 267 |
-
name: "
|
| 268 |
setup: func(m mox, a *Aggregator) {
|
| 269 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 270 |
m.proverMock.On("ID").Return(proverID).Twice()
|
| 271 |
m.proverMock.On("Addr").Return("addr")
|
| 272 |
-
m.stateMock.On("
|
| 273 |
},
|
| 274 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 275 |
assert.False(result)
|
|
@@ -277,7 +277,7 @@
|
|
| 277 |
},
|
| 278 |
},
|
| 279 |
{
|
| 280 |
-
name: "
|
| 281 |
setup: func(m mox, a *Aggregator) {
|
| 282 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 283 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
@@ -285,9 +285,9 @@
|
|
| 285 |
dbTx := &mocks.DbTxMock{}
|
| 286 |
dbTx.On("Rollback", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 287 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 288 |
-
m.stateMock.On("
|
| 289 |
m.stateMock.
|
| 290 |
-
On("
|
| 291 |
Run(func(args mock.Arguments) {
|
| 292 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 293 |
}).
|
|
@@ -300,7 +300,7 @@
|
|
| 300 |
},
|
| 301 |
},
|
| 302 |
{
|
| 303 |
-
name: "
|
| 304 |
setup: func(m mox, a *Aggregator) {
|
| 305 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 306 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
@@ -308,16 +308,16 @@
|
|
| 308 |
dbTx := &mocks.DbTxMock{}
|
| 309 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 310 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 311 |
-
m.stateMock.On("
|
| 312 |
proof1GeneratingTrueCall := m.stateMock.
|
| 313 |
-
On("
|
| 314 |
Run(func(args mock.Arguments) {
|
| 315 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 316 |
}).
|
| 317 |
Return(nil).
|
| 318 |
Once()
|
| 319 |
proof2GeneratingTrueCall := m.stateMock.
|
| 320 |
-
On("
|
| 321 |
Run(func(args mock.Arguments) {
|
| 322 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 323 |
}).
|
|
@@ -326,7 +326,7 @@
|
|
| 326 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(nil, errBanana).Once()
|
| 327 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 328 |
m.stateMock.
|
| 329 |
-
On("
|
| 330 |
Run(func(args mock.Arguments) {
|
| 331 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 332 |
}).
|
|
@@ -334,7 +334,7 @@
|
|
| 334 |
Once().
|
| 335 |
NotBefore(proof1GeneratingTrueCall)
|
| 336 |
m.stateMock.
|
| 337 |
-
On("
|
| 338 |
Run(func(args mock.Arguments) {
|
| 339 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 340 |
}).
|
|
@@ -357,16 +357,16 @@
|
|
| 357 |
dbTx := &mocks.DbTxMock{}
|
| 358 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 359 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 360 |
-
m.stateMock.On("
|
| 361 |
proof1GeneratingTrueCall := m.stateMock.
|
| 362 |
-
On("
|
| 363 |
Run(func(args mock.Arguments) {
|
| 364 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 365 |
}).
|
| 366 |
Return(nil).
|
| 367 |
Once()
|
| 368 |
proof2GeneratingTrueCall := m.stateMock.
|
| 369 |
-
On("
|
| 370 |
Run(func(args mock.Arguments) {
|
| 371 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 372 |
}).
|
|
@@ -376,7 +376,7 @@
|
|
| 376 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 377 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 378 |
m.stateMock.
|
| 379 |
-
On("
|
| 380 |
Run(func(args mock.Arguments) {
|
| 381 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 382 |
}).
|
|
@@ -384,7 +384,7 @@
|
|
| 384 |
Once().
|
| 385 |
NotBefore(proof1GeneratingTrueCall)
|
| 386 |
m.stateMock.
|
| 387 |
-
On("
|
| 388 |
Run(func(args mock.Arguments) {
|
| 389 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 390 |
}).
|
|
@@ -399,7 +399,7 @@
|
|
| 399 |
},
|
| 400 |
},
|
| 401 |
{
|
| 402 |
-
name: "
|
| 403 |
setup: func(m mox, a *Aggregator) {
|
| 404 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 405 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
@@ -407,16 +407,16 @@
|
|
| 407 |
dbTx := &mocks.DbTxMock{}
|
| 408 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 409 |
dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 410 |
-
m.stateMock.On("
|
| 411 |
proof1GeneratingTrueCall := m.stateMock.
|
| 412 |
-
On("
|
| 413 |
Run(func(args mock.Arguments) {
|
| 414 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 415 |
}).
|
| 416 |
Return(nil).
|
| 417 |
Once()
|
| 418 |
m.stateMock.
|
| 419 |
-
On("
|
| 420 |
Run(func(args mock.Arguments) {
|
| 421 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 422 |
}).
|
|
@@ -426,7 +426,7 @@
|
|
| 426 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 427 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 428 |
m.stateMock.
|
| 429 |
-
On("
|
| 430 |
Run(func(args mock.Arguments) {
|
| 431 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 432 |
}).
|
|
@@ -441,7 +441,7 @@
|
|
| 441 |
},
|
| 442 |
},
|
| 443 |
{
|
| 444 |
-
name: "rollback after
|
| 445 |
setup: func(m mox, a *Aggregator) {
|
| 446 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 447 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
@@ -449,16 +449,16 @@
|
|
| 449 |
dbTx := &mocks.DbTxMock{}
|
| 450 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 451 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 452 |
-
m.stateMock.On("
|
| 453 |
proof1GeneratingTrueCall := m.stateMock.
|
| 454 |
-
On("
|
| 455 |
Run(func(args mock.Arguments) {
|
| 456 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 457 |
}).
|
| 458 |
Return(nil).
|
| 459 |
Once()
|
| 460 |
proof2GeneratingTrueCall := m.stateMock.
|
| 461 |
-
On("
|
| 462 |
Run(func(args mock.Arguments) {
|
| 463 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 464 |
}).
|
|
@@ -466,11 +466,11 @@
|
|
| 466 |
Once()
|
| 467 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 468 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 469 |
-
m.stateMock.On("
|
| 470 |
dbTx.On("Rollback", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 471 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 472 |
m.stateMock.
|
| 473 |
-
On("
|
| 474 |
Run(func(args mock.Arguments) {
|
| 475 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 476 |
}).
|
|
@@ -478,7 +478,7 @@
|
|
| 478 |
Once().
|
| 479 |
NotBefore(proof1GeneratingTrueCall)
|
| 480 |
m.stateMock.
|
| 481 |
-
On("
|
| 482 |
Run(func(args mock.Arguments) {
|
| 483 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 484 |
}).
|
|
@@ -493,7 +493,7 @@
|
|
| 493 |
},
|
| 494 |
},
|
| 495 |
{
|
| 496 |
-
name: "rollback after
|
| 497 |
setup: func(m mox, a *Aggregator) {
|
| 498 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 499 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
@@ -501,16 +501,16 @@
|
|
| 501 |
dbTx := &mocks.DbTxMock{}
|
| 502 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 503 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 504 |
-
m.stateMock.On("
|
| 505 |
proof1GeneratingTrueCall := m.stateMock.
|
| 506 |
-
On("
|
| 507 |
Run(func(args mock.Arguments) {
|
| 508 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 509 |
}).
|
| 510 |
Return(nil).
|
| 511 |
Once()
|
| 512 |
proof2GeneratingTrueCall := m.stateMock.
|
| 513 |
-
On("
|
| 514 |
Run(func(args mock.Arguments) {
|
| 515 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 516 |
}).
|
|
@@ -518,12 +518,12 @@
|
|
| 518 |
Once()
|
| 519 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 520 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 521 |
-
m.stateMock.On("
|
| 522 |
-
m.stateMock.On("
|
| 523 |
dbTx.On("Rollback", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 524 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 525 |
m.stateMock.
|
| 526 |
-
On("
|
| 527 |
Run(func(args mock.Arguments) {
|
| 528 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 529 |
}).
|
|
@@ -531,7 +531,7 @@
|
|
| 531 |
Once().
|
| 532 |
NotBefore(proof1GeneratingTrueCall)
|
| 533 |
m.stateMock.
|
| 534 |
-
On("
|
| 535 |
Run(func(args mock.Arguments) {
|
| 536 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 537 |
}).
|
|
@@ -554,16 +554,16 @@
|
|
| 554 |
dbTx := &mocks.DbTxMock{}
|
| 555 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 556 |
dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Twice()
|
| 557 |
-
m.stateMock.On("
|
| 558 |
m.stateMock.
|
| 559 |
-
On("
|
| 560 |
Run(func(args mock.Arguments) {
|
| 561 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 562 |
}).
|
| 563 |
Return(nil).
|
| 564 |
Once()
|
| 565 |
m.stateMock.
|
| 566 |
-
On("
|
| 567 |
Run(func(args mock.Arguments) {
|
| 568 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 569 |
}).
|
|
@@ -571,14 +571,14 @@
|
|
| 571 |
Once()
|
| 572 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 573 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 574 |
-
m.stateMock.On("
|
| 575 |
expectedInputProver := map[string]interface{}{
|
| 576 |
"recursive_proof_1": proof1.Proof,
|
| 577 |
"recursive_proof_2": proof2.Proof,
|
| 578 |
}
|
| 579 |
b, err := json.Marshal(expectedInputProver)
|
| 580 |
require.NoError(err)
|
| 581 |
-
m.stateMock.On("
|
| 582 |
func(args mock.Arguments) {
|
| 583 |
proof := args[1].(*state.Proof)
|
| 584 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
@@ -590,7 +590,7 @@
|
|
| 590 |
assert.InDelta(time.Now().Unix(), proof.GeneratingSince.Unix(), float64(time.Second))
|
| 591 |
},
|
| 592 |
).Return(nil).Once()
|
| 593 |
-
m.stateMock.On("
|
| 594 |
func(args mock.Arguments) {
|
| 595 |
proof := args[1].(*state.Proof)
|
| 596 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
@@ -618,16 +618,16 @@
|
|
| 618 |
dbTx := &mocks.DbTxMock{}
|
| 619 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 620 |
dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Twice()
|
| 621 |
-
m.stateMock.On("
|
| 622 |
m.stateMock.
|
| 623 |
-
On("
|
| 624 |
Run(func(args mock.Arguments) {
|
| 625 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 626 |
}).
|
| 627 |
Return(nil).
|
| 628 |
Once()
|
| 629 |
m.stateMock.
|
| 630 |
-
On("
|
| 631 |
Run(func(args mock.Arguments) {
|
| 632 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 633 |
}).
|
|
@@ -635,14 +635,14 @@
|
|
| 635 |
Once()
|
| 636 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 637 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 638 |
-
m.stateMock.On("
|
| 639 |
expectedInputProver := map[string]interface{}{
|
| 640 |
"recursive_proof_1": proof1.Proof,
|
| 641 |
"recursive_proof_2": proof2.Proof,
|
| 642 |
}
|
| 643 |
b, err := json.Marshal(expectedInputProver)
|
| 644 |
require.NoError(err)
|
| 645 |
-
m.stateMock.On("
|
| 646 |
func(args mock.Arguments) {
|
| 647 |
proof := args[1].(*state.Proof)
|
| 648 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
@@ -660,7 +660,7 @@
|
|
| 660 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(uint64(42), nil).Once()
|
| 661 |
// make tryBuildFinalProof fail ASAP
|
| 662 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, errBanana).Once().NotBefore(isSyncedCall)
|
| 663 |
-
m.stateMock.On("
|
| 664 |
func(args mock.Arguments) {
|
| 665 |
proof := args[1].(*state.Proof)
|
| 666 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
@@ -686,7 +686,7 @@
|
|
| 686 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 687 |
etherman := mocks.NewEtherman(t)
|
| 688 |
proverMock := mocks.NewProverMock(t)
|
| 689 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 690 |
require.NoError(err)
|
| 691 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 692 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -701,7 +701,7 @@
|
|
| 701 |
}
|
| 702 |
a.resetVerifyProofTime()
|
| 703 |
|
| 704 |
-
result, err := a.
|
| 705 |
|
| 706 |
if tc.asserts != nil {
|
| 707 |
tc.asserts(result, &a, err)
|
|
@@ -777,7 +777,7 @@
|
|
| 777 |
m.proverMock.On("Addr").Return("addr")
|
| 778 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 779 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 780 |
-
m.stateMock.On("
|
| 781 |
func(args mock.Arguments) {
|
| 782 |
proof := args[1].(*state.Proof)
|
| 783 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
@@ -805,7 +805,7 @@
|
|
| 805 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 806 |
require.NoError(err)
|
| 807 |
m.proverMock.On("BatchProof", expectedInputProver).Return(nil, errBanana).Once()
|
| 808 |
-
m.stateMock.On("
|
| 809 |
},
|
| 810 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 811 |
assert.False(result)
|
|
@@ -820,7 +820,7 @@
|
|
| 820 |
m.proverMock.On("Addr").Return("addr")
|
| 821 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 822 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 823 |
-
m.stateMock.On("
|
| 824 |
func(args mock.Arguments) {
|
| 825 |
proof := args[1].(*state.Proof)
|
| 826 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
@@ -849,7 +849,7 @@
|
|
| 849 |
require.NoError(err)
|
| 850 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
| 851 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 852 |
-
m.stateMock.On("
|
| 853 |
},
|
| 854 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 855 |
assert.False(result)
|
|
@@ -857,14 +857,14 @@
|
|
| 857 |
},
|
| 858 |
},
|
| 859 |
{
|
| 860 |
-
name: "
|
| 861 |
setup: func(m mox, a *Aggregator) {
|
| 862 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 863 |
m.proverMock.On("ID").Return(proverID).Twice()
|
| 864 |
m.proverMock.On("Addr").Return(proverID)
|
| 865 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 866 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 867 |
-
m.stateMock.On("
|
| 868 |
func(args mock.Arguments) {
|
| 869 |
proof := args[1].(*state.Proof)
|
| 870 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
@@ -893,7 +893,7 @@
|
|
| 893 |
require.NoError(err)
|
| 894 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
| 895 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 896 |
-
m.stateMock.On("
|
| 897 |
},
|
| 898 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 899 |
assert.False(result)
|
|
@@ -908,7 +908,7 @@
|
|
| 908 |
m.proverMock.On("Addr").Return("addr")
|
| 909 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 910 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 911 |
-
m.stateMock.On("
|
| 912 |
func(args mock.Arguments) {
|
| 913 |
proof := args[1].(*state.Proof)
|
| 914 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
@@ -939,7 +939,7 @@
|
|
| 939 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 940 |
b, err := json.Marshal(expectedInputProver)
|
| 941 |
require.NoError(err)
|
| 942 |
-
m.stateMock.On("
|
| 943 |
func(args mock.Arguments) {
|
| 944 |
proof := args[1].(*state.Proof)
|
| 945 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
@@ -966,7 +966,7 @@
|
|
| 966 |
m.proverMock.On("Addr").Return("addr")
|
| 967 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 968 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 969 |
-
m.stateMock.On("
|
| 970 |
func(args mock.Arguments) {
|
| 971 |
proof := args[1].(*state.Proof)
|
| 972 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
@@ -1003,7 +1003,7 @@
|
|
| 1003 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 1004 |
// make tryBuildFinalProof fail ASAP
|
| 1005 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, errBanana).Once().NotBefore(isSyncedCall)
|
| 1006 |
-
m.stateMock.On("
|
| 1007 |
func(args mock.Arguments) {
|
| 1008 |
proof := args[1].(*state.Proof)
|
| 1009 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
@@ -1029,7 +1029,7 @@
|
|
| 1029 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1030 |
etherman := mocks.NewEtherman(t)
|
| 1031 |
proverMock := mocks.NewProverMock(t)
|
| 1032 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 1033 |
require.NoError(err)
|
| 1034 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1035 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -1138,11 +1138,11 @@
|
|
| 1138 |
m.proverMock.On("Addr").Return("addr").Twice()
|
| 1139 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1140 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1141 |
-
m.stateMock.On("
|
| 1142 |
-
proofGeneratingTrueCall := m.stateMock.On("
|
| 1143 |
m.proverMock.On("FinalProof", proofToVerify.Proof, from.String()).Return(nil, errBanana).Once()
|
| 1144 |
m.stateMock.
|
| 1145 |
-
On("
|
| 1146 |
Return(nil).
|
| 1147 |
Once().
|
| 1148 |
NotBefore(proofGeneratingTrueCall)
|
|
@@ -1160,12 +1160,12 @@
|
|
| 1160 |
m.proverMock.On("Addr").Return("addr").Twice()
|
| 1161 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1162 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1163 |
-
m.stateMock.On("
|
| 1164 |
-
proofGeneratingTrueCall := m.stateMock.On("
|
| 1165 |
m.proverMock.On("FinalProof", proofToVerify.Proof, from.String()).Return(&finalProofID, nil).Once()
|
| 1166 |
m.proverMock.On("WaitFinalProof", mock.MatchedBy(matchProverCtxFn), finalProofID).Return(nil, errBanana).Once()
|
| 1167 |
m.stateMock.
|
| 1168 |
-
On("
|
| 1169 |
Return(nil).
|
| 1170 |
Once().
|
| 1171 |
NotBefore(proofGeneratingTrueCall)
|
|
@@ -1183,7 +1183,7 @@
|
|
| 1183 |
m.proverMock.On("Addr").Return(proverID).Once()
|
| 1184 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1185 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1186 |
-
m.stateMock.On("
|
| 1187 |
},
|
| 1188 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 1189 |
assert.False(result)
|
|
@@ -1198,7 +1198,7 @@
|
|
| 1198 |
m.proverMock.On("Addr").Return(proverID).Once()
|
| 1199 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1200 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1201 |
-
m.stateMock.On("
|
| 1202 |
},
|
| 1203 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 1204 |
assert.False(result)
|
|
@@ -1213,8 +1213,8 @@
|
|
| 1213 |
m.proverMock.On("Addr").Return(proverID).Twice()
|
| 1214 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1215 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1216 |
-
m.stateMock.On("
|
| 1217 |
-
m.stateMock.On("
|
| 1218 |
m.proverMock.On("FinalProof", proofToVerify.Proof, from.String()).Return(&finalProofID, nil).Once()
|
| 1219 |
m.proverMock.On("WaitFinalProof", mock.MatchedBy(matchProverCtxFn), finalProofID).Return(&finalProof, nil).Once()
|
| 1220 |
},
|
|
@@ -1306,7 +1306,7 @@
|
|
| 1306 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1307 |
etherman := mocks.NewEtherman(t)
|
| 1308 |
proverMock := mocks.NewProverMock(t)
|
| 1309 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 1310 |
require.NoError(err)
|
| 1311 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1312 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -1436,7 +1436,7 @@
|
|
| 1436 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1437 |
etherman := mocks.NewEtherman(t)
|
| 1438 |
proverMock := mocks.NewProverMock(t)
|
| 1439 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 1440 |
require.NoError(err)
|
| 1441 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1442 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -1450,9 +1450,79 @@
|
|
| 1450 |
tc.setup(m, &a)
|
| 1451 |
}
|
| 1452 |
|
| 1453 |
-
synced := a.isSynced(a.ctx, tc.batchNum)
|
| 1454 |
-
|
| 1455 |
assert.Equal(tc.synced, synced)
|
| 1456 |
})
|
| 1457 |
}
|
| 1458 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
m.etherman.On("BuildTrustedVerifyBatchesTxData", batchNum-1, batchNumFinal, &expectedInputs, common.HexToAddress(cfg.SenderAddress)).Run(func(args mock.Arguments) {
|
| 90 |
assert.True(a.verifyingProof)
|
| 91 |
}).Return(nil, nil, errBanana).Once()
|
| 92 |
+
m.stateMock.On("UpdateGeneratedProof", mock.Anything, recursiveProof, nil).Run(func(args mock.Arguments) {
|
| 93 |
// test is done, stop the sendFinalProof method
|
| 94 |
a.exit()
|
| 95 |
}).Return(nil).Once()
|
|
|
|
| 99 |
},
|
| 100 |
},
|
| 101 |
{
|
| 102 |
+
name: "UpdateGeneratedProof error after BuildTrustedVerifyBatchesTxData error",
|
| 103 |
setup: func(m mox, a *Aggregator) {
|
| 104 |
m.stateMock.On("GetBatchByNumber", mock.Anything, batchNumFinal, nil).Run(func(args mock.Arguments) {
|
| 105 |
assert.True(a.verifyingProof)
|
|
|
|
| 112 |
m.etherman.On("BuildTrustedVerifyBatchesTxData", batchNum-1, batchNumFinal, &expectedInputs, common.HexToAddress(cfg.SenderAddress)).Run(func(args mock.Arguments) {
|
| 113 |
assert.True(a.verifyingProof)
|
| 114 |
}).Return(nil, nil, errBanana).Once()
|
| 115 |
+
m.stateMock.On("UpdateGeneratedProof", mock.Anything, recursiveProof, nil).Run(func(args mock.Arguments) {
|
| 116 |
// test is done, stop the sendFinalProof method
|
| 117 |
a.exit()
|
| 118 |
}).Return(errBanana).Once()
|
|
|
|
| 137 |
}).Return(&to, data, nil).Once()
|
| 138 |
monitoredTxID := buildMonitoredTxID(batchNum, batchNumFinal)
|
| 139 |
m.ethTxManager.On("Add", mock.Anything, ethTxManagerOwner, monitoredTxID, from, &to, value, data, cfg.GasOffset, nil).Return(errBanana).Once()
|
| 140 |
+
m.stateMock.On("UpdateGeneratedProof", mock.Anything, recursiveProof, nil).Run(func(args mock.Arguments) {
|
| 141 |
// test is done, stop the sendFinalProof method
|
| 142 |
a.exit()
|
| 143 |
}).Return(nil).Once()
|
|
|
|
| 175 |
}
|
| 176 |
m.stateMock.On("GetLastVerifiedBatch", mock.Anything, nil).Return(&verifiedBatch, nil).Once()
|
| 177 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(batchNumFinal, nil).Once()
|
| 178 |
+
m.stateMock.On("CleanupGeneratedProofs", mock.Anything, batchNumFinal, nil).Run(func(args mock.Arguments) {
|
| 179 |
// test is done, stop the sendFinalProof method
|
| 180 |
a.exit()
|
| 181 |
}).Return(nil).Once()
|
|
|
|
| 191 |
stateMock := mocks.NewStateMock(t)
|
| 192 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 193 |
etherman := mocks.NewEtherman(t)
|
| 194 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 195 |
require.NoError(err)
|
| 196 |
a.ctx, a.exit = context.WithCancel(context.Background())
|
| 197 |
m := mox{
|
|
|
|
| 251 |
asserts func(bool, *Aggregator, error)
|
| 252 |
}{
|
| 253 |
{
|
| 254 |
+
name: "getAndLockProofsToAggregate returns generic error",
|
| 255 |
setup: func(m mox, a *Aggregator) {
|
| 256 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 257 |
m.proverMock.On("ID").Return(proverID).Twice()
|
| 258 |
m.proverMock.On("Addr").Return("addr")
|
| 259 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, nil, errBanana).Once()
|
| 260 |
},
|
| 261 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 262 |
assert.False(result)
|
|
|
|
| 264 |
},
|
| 265 |
},
|
| 266 |
{
|
| 267 |
+
name: "getAndLockProofsToAggregate returns ErrNotFound",
|
| 268 |
setup: func(m mox, a *Aggregator) {
|
| 269 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 270 |
m.proverMock.On("ID").Return(proverID).Twice()
|
| 271 |
m.proverMock.On("Addr").Return("addr")
|
| 272 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, nil, state.ErrNotFound).Once()
|
| 273 |
},
|
| 274 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 275 |
assert.False(result)
|
|
|
|
| 277 |
},
|
| 278 |
},
|
| 279 |
{
|
| 280 |
+
name: "getAndLockProofsToAggregate error updating proofs",
|
| 281 |
setup: func(m mox, a *Aggregator) {
|
| 282 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 283 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
|
|
| 285 |
dbTx := &mocks.DbTxMock{}
|
| 286 |
dbTx.On("Rollback", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 287 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 288 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 289 |
m.stateMock.
|
| 290 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 291 |
Run(func(args mock.Arguments) {
|
| 292 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 293 |
}).
|
|
|
|
| 300 |
},
|
| 301 |
},
|
| 302 |
{
|
| 303 |
+
name: "AggregatedProof prover error",
|
| 304 |
setup: func(m mox, a *Aggregator) {
|
| 305 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 306 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
|
|
| 308 |
dbTx := &mocks.DbTxMock{}
|
| 309 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 310 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 311 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 312 |
proof1GeneratingTrueCall := m.stateMock.
|
| 313 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 314 |
Run(func(args mock.Arguments) {
|
| 315 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 316 |
}).
|
| 317 |
Return(nil).
|
| 318 |
Once()
|
| 319 |
proof2GeneratingTrueCall := m.stateMock.
|
| 320 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof2, dbTx).
|
| 321 |
Run(func(args mock.Arguments) {
|
| 322 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 323 |
}).
|
|
|
|
| 326 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(nil, errBanana).Once()
|
| 327 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 328 |
m.stateMock.
|
| 329 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof1, dbTx).
|
| 330 |
Run(func(args mock.Arguments) {
|
| 331 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 332 |
}).
|
|
|
|
| 334 |
Once().
|
| 335 |
NotBefore(proof1GeneratingTrueCall)
|
| 336 |
m.stateMock.
|
| 337 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof2, dbTx).
|
| 338 |
Run(func(args mock.Arguments) {
|
| 339 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 340 |
}).
|
|
|
|
| 357 |
dbTx := &mocks.DbTxMock{}
|
| 358 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 359 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 360 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 361 |
proof1GeneratingTrueCall := m.stateMock.
|
| 362 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 363 |
Run(func(args mock.Arguments) {
|
| 364 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 365 |
}).
|
| 366 |
Return(nil).
|
| 367 |
Once()
|
| 368 |
proof2GeneratingTrueCall := m.stateMock.
|
| 369 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof2, dbTx).
|
| 370 |
Run(func(args mock.Arguments) {
|
| 371 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 372 |
}).
|
|
|
|
| 376 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 377 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 378 |
m.stateMock.
|
| 379 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof1, dbTx).
|
| 380 |
Run(func(args mock.Arguments) {
|
| 381 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 382 |
}).
|
|
|
|
| 384 |
Once().
|
| 385 |
NotBefore(proof1GeneratingTrueCall)
|
| 386 |
m.stateMock.
|
| 387 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof2, dbTx).
|
| 388 |
Run(func(args mock.Arguments) {
|
| 389 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 390 |
}).
|
|
|
|
| 399 |
},
|
| 400 |
},
|
| 401 |
{
|
| 402 |
+
name: "unlockProofsToAggregate error after WaitRecursiveProof prover error",
|
| 403 |
setup: func(m mox, a *Aggregator) {
|
| 404 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 405 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
|
|
| 407 |
dbTx := &mocks.DbTxMock{}
|
| 408 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Once()
|
| 409 |
dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 410 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 411 |
proof1GeneratingTrueCall := m.stateMock.
|
| 412 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 413 |
Run(func(args mock.Arguments) {
|
| 414 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 415 |
}).
|
| 416 |
Return(nil).
|
| 417 |
Once()
|
| 418 |
m.stateMock.
|
| 419 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof2, dbTx).
|
| 420 |
Run(func(args mock.Arguments) {
|
| 421 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 422 |
}).
|
|
|
|
| 426 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 427 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 428 |
m.stateMock.
|
| 429 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof1, dbTx).
|
| 430 |
Run(func(args mock.Arguments) {
|
| 431 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 432 |
}).
|
|
|
|
| 441 |
},
|
| 442 |
},
|
| 443 |
{
|
| 444 |
+
name: "rollback after DeleteGeneratedProofs error in db transaction",
|
| 445 |
setup: func(m mox, a *Aggregator) {
|
| 446 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 447 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
|
|
| 449 |
dbTx := &mocks.DbTxMock{}
|
| 450 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 451 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 452 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 453 |
proof1GeneratingTrueCall := m.stateMock.
|
| 454 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 455 |
Run(func(args mock.Arguments) {
|
| 456 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 457 |
}).
|
| 458 |
Return(nil).
|
| 459 |
Once()
|
| 460 |
proof2GeneratingTrueCall := m.stateMock.
|
| 461 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof2, dbTx).
|
| 462 |
Run(func(args mock.Arguments) {
|
| 463 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 464 |
}).
|
|
|
|
| 466 |
Once()
|
| 467 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 468 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 469 |
+
m.stateMock.On("DeleteGeneratedProofs", mock.MatchedBy(matchProverCtxFn), proof1.BatchNumber, proof2.BatchNumberFinal, dbTx).Return(errBanana).Once()
|
| 470 |
dbTx.On("Rollback", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 471 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 472 |
m.stateMock.
|
| 473 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof1, dbTx).
|
| 474 |
Run(func(args mock.Arguments) {
|
| 475 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 476 |
}).
|
|
|
|
| 478 |
Once().
|
| 479 |
NotBefore(proof1GeneratingTrueCall)
|
| 480 |
m.stateMock.
|
| 481 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof2, dbTx).
|
| 482 |
Run(func(args mock.Arguments) {
|
| 483 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 484 |
}).
|
|
|
|
| 493 |
},
|
| 494 |
},
|
| 495 |
{
|
| 496 |
+
name: "rollback after AddGeneratedProof error in db transaction",
|
| 497 |
setup: func(m mox, a *Aggregator) {
|
| 498 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 499 |
m.proverMock.On("ID").Return(proverID).Twice()
|
|
|
|
| 501 |
dbTx := &mocks.DbTxMock{}
|
| 502 |
lockProofsTxBegin := m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 503 |
lockProofsTxCommit := dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 504 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 505 |
proof1GeneratingTrueCall := m.stateMock.
|
| 506 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 507 |
Run(func(args mock.Arguments) {
|
| 508 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 509 |
}).
|
| 510 |
Return(nil).
|
| 511 |
Once()
|
| 512 |
proof2GeneratingTrueCall := m.stateMock.
|
| 513 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof2, dbTx).
|
| 514 |
Run(func(args mock.Arguments) {
|
| 515 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 516 |
}).
|
|
|
|
| 518 |
Once()
|
| 519 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 520 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 521 |
+
m.stateMock.On("DeleteGeneratedProofs", mock.MatchedBy(matchProverCtxFn), proof1.BatchNumber, proof2.BatchNumberFinal, dbTx).Return(nil).Once()
|
| 522 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, dbTx).Return(errBanana).Once()
|
| 523 |
dbTx.On("Rollback", mock.MatchedBy(matchProverCtxFn)).Return(nil).Once()
|
| 524 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchAggregatorCtxFn)).Return(dbTx, nil).Once().NotBefore(lockProofsTxBegin)
|
| 525 |
m.stateMock.
|
| 526 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof1, dbTx).
|
| 527 |
Run(func(args mock.Arguments) {
|
| 528 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 529 |
}).
|
|
|
|
| 531 |
Once().
|
| 532 |
NotBefore(proof1GeneratingTrueCall)
|
| 533 |
m.stateMock.
|
| 534 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proof2, dbTx).
|
| 535 |
Run(func(args mock.Arguments) {
|
| 536 |
assert.Nil(args[1].(*state.Proof).GeneratingSince)
|
| 537 |
}).
|
|
|
|
| 554 |
dbTx := &mocks.DbTxMock{}
|
| 555 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 556 |
dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Twice()
|
| 557 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 558 |
m.stateMock.
|
| 559 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 560 |
Run(func(args mock.Arguments) {
|
| 561 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 562 |
}).
|
| 563 |
Return(nil).
|
| 564 |
Once()
|
| 565 |
m.stateMock.
|
| 566 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof2, dbTx).
|
| 567 |
Run(func(args mock.Arguments) {
|
| 568 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 569 |
}).
|
|
|
|
| 571 |
Once()
|
| 572 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 573 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 574 |
+
m.stateMock.On("DeleteGeneratedProofs", mock.MatchedBy(matchProverCtxFn), proof1.BatchNumber, proof2.BatchNumberFinal, dbTx).Return(nil).Once()
|
| 575 |
expectedInputProver := map[string]interface{}{
|
| 576 |
"recursive_proof_1": proof1.Proof,
|
| 577 |
"recursive_proof_2": proof2.Proof,
|
| 578 |
}
|
| 579 |
b, err := json.Marshal(expectedInputProver)
|
| 580 |
require.NoError(err)
|
| 581 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, dbTx).Run(
|
| 582 |
func(args mock.Arguments) {
|
| 583 |
proof := args[1].(*state.Proof)
|
| 584 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
|
|
| 590 |
assert.InDelta(time.Now().Unix(), proof.GeneratingSince.Unix(), float64(time.Second))
|
| 591 |
},
|
| 592 |
).Return(nil).Once()
|
| 593 |
+
m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), mock.Anything, nil).Run(
|
| 594 |
func(args mock.Arguments) {
|
| 595 |
proof := args[1].(*state.Proof)
|
| 596 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
|
|
| 618 |
dbTx := &mocks.DbTxMock{}
|
| 619 |
m.stateMock.On("BeginStateTransaction", mock.MatchedBy(matchProverCtxFn)).Return(dbTx, nil).Twice()
|
| 620 |
dbTx.On("Commit", mock.MatchedBy(matchProverCtxFn)).Return(nil).Twice()
|
| 621 |
+
m.stateMock.On("GetProofsToAggregate", mock.MatchedBy(matchProverCtxFn), nil).Return(&proof1, &proof2, nil).Once()
|
| 622 |
m.stateMock.
|
| 623 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof1, dbTx).
|
| 624 |
Run(func(args mock.Arguments) {
|
| 625 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 626 |
}).
|
| 627 |
Return(nil).
|
| 628 |
Once()
|
| 629 |
m.stateMock.
|
| 630 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proof2, dbTx).
|
| 631 |
Run(func(args mock.Arguments) {
|
| 632 |
assert.NotNil(args[1].(*state.Proof).GeneratingSince)
|
| 633 |
}).
|
|
|
|
| 635 |
Once()
|
| 636 |
m.proverMock.On("AggregatedProof", proof1.Proof, proof2.Proof).Return(&proofID, nil).Once()
|
| 637 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 638 |
+
m.stateMock.On("DeleteGeneratedProofs", mock.MatchedBy(matchProverCtxFn), proof1.BatchNumber, proof2.BatchNumberFinal, dbTx).Return(nil).Once()
|
| 639 |
expectedInputProver := map[string]interface{}{
|
| 640 |
"recursive_proof_1": proof1.Proof,
|
| 641 |
"recursive_proof_2": proof2.Proof,
|
| 642 |
}
|
| 643 |
b, err := json.Marshal(expectedInputProver)
|
| 644 |
require.NoError(err)
|
| 645 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, dbTx).Run(
|
| 646 |
func(args mock.Arguments) {
|
| 647 |
proof := args[1].(*state.Proof)
|
| 648 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
|
|
| 660 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(uint64(42), nil).Once()
|
| 661 |
// make tryBuildFinalProof fail ASAP
|
| 662 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, errBanana).Once().NotBefore(isSyncedCall)
|
| 663 |
+
m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), mock.Anything, nil).Run(
|
| 664 |
func(args mock.Arguments) {
|
| 665 |
proof := args[1].(*state.Proof)
|
| 666 |
assert.Equal(proof1.BatchNumber, proof.BatchNumber)
|
|
|
|
| 686 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 687 |
etherman := mocks.NewEtherman(t)
|
| 688 |
proverMock := mocks.NewProverMock(t)
|
| 689 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 690 |
require.NoError(err)
|
| 691 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 692 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 701 |
}
|
| 702 |
a.resetVerifyProofTime()
|
| 703 |
|
| 704 |
+
result, err := a.tryAggregateProofs(proverCtx, proverMock)
|
| 705 |
|
| 706 |
if tc.asserts != nil {
|
| 707 |
tc.asserts(result, &a, err)
|
|
|
|
| 777 |
m.proverMock.On("Addr").Return("addr")
|
| 778 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 779 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 780 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run(
|
| 781 |
func(args mock.Arguments) {
|
| 782 |
proof := args[1].(*state.Proof)
|
| 783 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
|
|
| 805 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 806 |
require.NoError(err)
|
| 807 |
m.proverMock.On("BatchProof", expectedInputProver).Return(nil, errBanana).Once()
|
| 808 |
+
m.stateMock.On("DeleteGeneratedProofs", mock.MatchedBy(matchAggregatorCtxFn), batchToProve.BatchNumber, batchToProve.BatchNumber, nil).Return(nil).Once()
|
| 809 |
},
|
| 810 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 811 |
assert.False(result)
|
|
|
|
| 820 |
m.proverMock.On("Addr").Return("addr")
|
| 821 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 822 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 823 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run(
|
| 824 |
func(args mock.Arguments) {
|
| 825 |
proof := args[1].(*state.Proof)
|
| 826 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
|
|
| 849 |
require.NoError(err)
|
| 850 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
| 851 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 852 |
+
m.stateMock.On("DeleteGeneratedProofs", mock.MatchedBy(matchAggregatorCtxFn), batchToProve.BatchNumber, batchToProve.BatchNumber, nil).Return(nil).Once()
|
| 853 |
},
|
| 854 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 855 |
assert.False(result)
|
|
|
|
| 857 |
},
|
| 858 |
},
|
| 859 |
{
|
| 860 |
+
name: "DeleteGeneratedProofs error after WaitRecursiveProof prover error",
|
| 861 |
setup: func(m mox, a *Aggregator) {
|
| 862 |
m.proverMock.On("Name").Return(proverName).Twice()
|
| 863 |
m.proverMock.On("ID").Return(proverID).Twice()
|
| 864 |
m.proverMock.On("Addr").Return(proverID)
|
| 865 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 866 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 867 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run(
|
| 868 |
func(args mock.Arguments) {
|
| 869 |
proof := args[1].(*state.Proof)
|
| 870 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
|
|
| 893 |
require.NoError(err)
|
| 894 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
| 895 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return("", errBanana).Once()
|
| 896 |
+
m.stateMock.On("DeleteGeneratedProofs", mock.MatchedBy(matchAggregatorCtxFn), batchToProve.BatchNumber, batchToProve.BatchNumber, nil).Return(errBanana).Once()
|
| 897 |
},
|
| 898 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 899 |
assert.False(result)
|
|
|
|
| 908 |
m.proverMock.On("Addr").Return("addr")
|
| 909 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 910 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 911 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run(
|
| 912 |
func(args mock.Arguments) {
|
| 913 |
proof := args[1].(*state.Proof)
|
| 914 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
|
|
| 939 |
m.proverMock.On("WaitRecursiveProof", mock.MatchedBy(matchProverCtxFn), proofID).Return(recursiveProof, nil).Once()
|
| 940 |
b, err := json.Marshal(expectedInputProver)
|
| 941 |
require.NoError(err)
|
| 942 |
+
m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), mock.Anything, nil).Run(
|
| 943 |
func(args mock.Arguments) {
|
| 944 |
proof := args[1].(*state.Proof)
|
| 945 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
|
|
| 966 |
m.proverMock.On("Addr").Return("addr")
|
| 967 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once()
|
| 968 |
m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once()
|
| 969 |
+
m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run(
|
| 970 |
func(args mock.Arguments) {
|
| 971 |
proof := args[1].(*state.Proof)
|
| 972 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
|
|
| 1003 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 1004 |
// make tryBuildFinalProof fail ASAP
|
| 1005 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, errBanana).Once().NotBefore(isSyncedCall)
|
| 1006 |
+
m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), mock.Anything, nil).Run(
|
| 1007 |
func(args mock.Arguments) {
|
| 1008 |
proof := args[1].(*state.Proof)
|
| 1009 |
assert.Equal(batchToProve.BatchNumber, proof.BatchNumber)
|
|
|
|
| 1029 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1030 |
etherman := mocks.NewEtherman(t)
|
| 1031 |
proverMock := mocks.NewProverMock(t)
|
| 1032 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 1033 |
require.NoError(err)
|
| 1034 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1035 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 1138 |
m.proverMock.On("Addr").Return("addr").Twice()
|
| 1139 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1140 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1141 |
+
m.stateMock.On("GetProofReadyToVerify", mock.MatchedBy(matchProverCtxFn), latestVerifiedBatchNum, nil).Return(&proofToVerify, nil).Once()
|
| 1142 |
+
proofGeneratingTrueCall := m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proofToVerify, nil).Return(nil).Once()
|
| 1143 |
m.proverMock.On("FinalProof", proofToVerify.Proof, from.String()).Return(nil, errBanana).Once()
|
| 1144 |
m.stateMock.
|
| 1145 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proofToVerify, nil).
|
| 1146 |
Return(nil).
|
| 1147 |
Once().
|
| 1148 |
NotBefore(proofGeneratingTrueCall)
|
|
|
|
| 1160 |
m.proverMock.On("Addr").Return("addr").Twice()
|
| 1161 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1162 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1163 |
+
m.stateMock.On("GetProofReadyToVerify", mock.MatchedBy(matchProverCtxFn), latestVerifiedBatchNum, nil).Return(&proofToVerify, nil).Once()
|
| 1164 |
+
proofGeneratingTrueCall := m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proofToVerify, nil).Return(nil).Once()
|
| 1165 |
m.proverMock.On("FinalProof", proofToVerify.Proof, from.String()).Return(&finalProofID, nil).Once()
|
| 1166 |
m.proverMock.On("WaitFinalProof", mock.MatchedBy(matchProverCtxFn), finalProofID).Return(nil, errBanana).Once()
|
| 1167 |
m.stateMock.
|
| 1168 |
+
On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), &proofToVerify, nil).
|
| 1169 |
Return(nil).
|
| 1170 |
Once().
|
| 1171 |
NotBefore(proofGeneratingTrueCall)
|
|
|
|
| 1183 |
m.proverMock.On("Addr").Return(proverID).Once()
|
| 1184 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1185 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1186 |
+
m.stateMock.On("GetProofReadyToVerify", mock.MatchedBy(matchProverCtxFn), latestVerifiedBatchNum, nil).Return(nil, errBanana).Once()
|
| 1187 |
},
|
| 1188 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 1189 |
assert.False(result)
|
|
|
|
| 1198 |
m.proverMock.On("Addr").Return(proverID).Once()
|
| 1199 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1200 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1201 |
+
m.stateMock.On("GetProofReadyToVerify", mock.MatchedBy(matchProverCtxFn), latestVerifiedBatchNum, nil).Return(nil, state.ErrNotFound).Once()
|
| 1202 |
},
|
| 1203 |
asserts: func(result bool, a *Aggregator, err error) {
|
| 1204 |
assert.False(result)
|
|
|
|
| 1213 |
m.proverMock.On("Addr").Return(proverID).Twice()
|
| 1214 |
m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&verifiedBatch, nil).Twice()
|
| 1215 |
m.etherman.On("GetLatestVerifiedBatchNum").Return(latestVerifiedBatchNum, nil).Once()
|
| 1216 |
+
m.stateMock.On("GetProofReadyToVerify", mock.MatchedBy(matchProverCtxFn), latestVerifiedBatchNum, nil).Return(&proofToVerify, nil).Once()
|
| 1217 |
+
m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchProverCtxFn), &proofToVerify, nil).Return(nil).Once()
|
| 1218 |
m.proverMock.On("FinalProof", proofToVerify.Proof, from.String()).Return(&finalProofID, nil).Once()
|
| 1219 |
m.proverMock.On("WaitFinalProof", mock.MatchedBy(matchProverCtxFn), finalProofID).Return(&finalProof, nil).Once()
|
| 1220 |
},
|
|
|
|
| 1306 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1307 |
etherman := mocks.NewEtherman(t)
|
| 1308 |
proverMock := mocks.NewProverMock(t)
|
| 1309 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 1310 |
require.NoError(err)
|
| 1311 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1312 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 1436 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1437 |
etherman := mocks.NewEtherman(t)
|
| 1438 |
proverMock := mocks.NewProverMock(t)
|
| 1439 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 1440 |
require.NoError(err)
|
| 1441 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1442 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 1450 |
tc.setup(m, &a)
|
| 1451 |
}
|
| 1452 |
|
| 1453 |
+
synced, _ := a.isSynced(a.ctx, tc.batchNum)
|
|
|
|
| 1454 |
assert.Equal(tc.synced, synced)
|
| 1455 |
})
|
| 1456 |
}
|
| 1457 |
}
|
| 1458 |
+
|
| 1459 |
+
func TestWaitForSynchronizerToSyncUp(t *testing.T) {
|
| 1460 |
+
t.Parallel()
|
| 1461 |
+
|
| 1462 |
+
cfg := Config{}
|
| 1463 |
+
batchNum := uint64(42)
|
| 1464 |
+
testCases := []struct {
|
| 1465 |
+
name string
|
| 1466 |
+
setup func(mox, *Aggregator)
|
| 1467 |
+
batchNum *uint64
|
| 1468 |
+
synced bool
|
| 1469 |
+
}{
|
| 1470 |
+
{
|
| 1471 |
+
name: "state context canceled",
|
| 1472 |
+
synced: false,
|
| 1473 |
+
batchNum: &batchNum,
|
| 1474 |
+
setup: func(m mox, a *Aggregator) {
|
| 1475 |
+
m.stateMock.On("GetLastVerifiedBatch", mock.Anything, nil).Return(nil, context.Canceled).Once()
|
| 1476 |
+
},
|
| 1477 |
+
},
|
| 1478 |
+
{
|
| 1479 |
+
name: "ok after multiple iterations",
|
| 1480 |
+
synced: true,
|
| 1481 |
+
batchNum: &batchNum,
|
| 1482 |
+
setup: func(m mox, a *Aggregator) {
|
| 1483 |
+
latestVerifiedBatch := state.VerifiedBatch{BatchNumber: batchNum}
|
| 1484 |
+
m.stateMock.On("GetLastVerifiedBatch", mock.Anything, nil).Return(nil, nil).Once()
|
| 1485 |
+
m.stateMock.On("GetLastVerifiedBatch", mock.Anything, nil).Return(&latestVerifiedBatch, nil).Once()
|
| 1486 |
+
m.etherman.On("GetLatestVerifiedBatchNum").Return(batchNum, nil).Once()
|
| 1487 |
+
},
|
| 1488 |
+
},
|
| 1489 |
+
{
|
| 1490 |
+
name: "ok with batch number",
|
| 1491 |
+
synced: true,
|
| 1492 |
+
batchNum: &batchNum,
|
| 1493 |
+
setup: func(m mox, a *Aggregator) {
|
| 1494 |
+
latestVerifiedBatch := state.VerifiedBatch{BatchNumber: batchNum}
|
| 1495 |
+
m.stateMock.On("GetLastVerifiedBatch", mock.Anything, nil).Return(&latestVerifiedBatch, nil).Once()
|
| 1496 |
+
m.etherman.On("GetLatestVerifiedBatchNum").Return(batchNum, nil).Once()
|
| 1497 |
+
},
|
| 1498 |
+
},
|
| 1499 |
+
}
|
| 1500 |
+
for _, tc := range testCases {
|
| 1501 |
+
t.Run(tc.name, func(t *testing.T) {
|
| 1502 |
+
stateMock := mocks.NewStateMock(t)
|
| 1503 |
+
ethTxManager := mocks.NewEthTxManager(t)
|
| 1504 |
+
etherman := mocks.NewEtherman(t)
|
| 1505 |
+
proverMock := mocks.NewProverMock(t)
|
| 1506 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 1507 |
+
require.NoError(t, err)
|
| 1508 |
+
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1509 |
+
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
| 1510 |
+
m := mox{
|
| 1511 |
+
stateMock: stateMock,
|
| 1512 |
+
ethTxManager: ethTxManager,
|
| 1513 |
+
etherman: etherman,
|
| 1514 |
+
proverMock: proverMock,
|
| 1515 |
+
}
|
| 1516 |
+
if tc.setup != nil {
|
| 1517 |
+
tc.setup(m, &a)
|
| 1518 |
+
}
|
| 1519 |
+
|
| 1520 |
+
err = a.waitForSynchronizerToSyncUp(a.ctx, tc.batchNum)
|
| 1521 |
+
if tc.synced {
|
| 1522 |
+
assert.NoError(t, err)
|
| 1523 |
+
} else {
|
| 1524 |
+
assert.Error(t, err)
|
| 1525 |
+
}
|
| 1526 |
+
})
|
| 1527 |
+
}
|
| 1528 |
+
}
|
|
@@ -1,427 +0,0 @@
|
|
| 1 |
-
package aggregator
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"encoding/json"
|
| 6 |
-
"errors"
|
| 7 |
-
"fmt"
|
| 8 |
-
"math/big"
|
| 9 |
-
"time"
|
| 10 |
-
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 12 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 13 |
-
)
|
| 14 |
-
|
| 15 |
-
func (a *Aggregator) tryGenerateBatchProof(ctx context.Context, prover proverInterface) (bool, error) {
|
| 16 |
-
log := log.WithFields(
|
| 17 |
-
"prover", prover.Name(),
|
| 18 |
-
"proverId", prover.ID(),
|
| 19 |
-
"proverAddr", prover.Addr(),
|
| 20 |
-
)
|
| 21 |
-
log.Debug("tryGenerateBatchProof start")
|
| 22 |
-
|
| 23 |
-
batchToProve, proof, err0 := a.getAndLockBatchToProve(ctx, prover)
|
| 24 |
-
if errors.Is(err0, state.ErrNotFound) {
|
| 25 |
-
// nothing to proof, swallow the error
|
| 26 |
-
log.Debug("Nothing to generate proof")
|
| 27 |
-
return false, nil
|
| 28 |
-
}
|
| 29 |
-
if err0 != nil {
|
| 30 |
-
return false, err0
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
log = log.WithFields("batch", batchToProve.BatchNumber)
|
| 34 |
-
|
| 35 |
-
var (
|
| 36 |
-
genProofID *string
|
| 37 |
-
err error
|
| 38 |
-
)
|
| 39 |
-
|
| 40 |
-
defer func() {
|
| 41 |
-
if err != nil {
|
| 42 |
-
err2 := a.State.DeleteBatchProofs(a.ctx, proof.BatchNumber, proof.BatchNumberFinal, nil)
|
| 43 |
-
if err2 != nil {
|
| 44 |
-
log.Errorf("Failed to delete proof in progress, err: %v", err2)
|
| 45 |
-
}
|
| 46 |
-
}
|
| 47 |
-
log.Debug("tryGenerateBatchProof end")
|
| 48 |
-
}()
|
| 49 |
-
|
| 50 |
-
log.Info("Generating proof from batch")
|
| 51 |
-
|
| 52 |
-
log.Infof("Sending zki + batch to the prover, batchNumber [%d]", batchToProve.BatchNumber)
|
| 53 |
-
inputProver, err := a.buildInputProver(ctx, batchToProve)
|
| 54 |
-
if err != nil {
|
| 55 |
-
err = fmt.Errorf("failed to build input prover, %w", err)
|
| 56 |
-
log.Error(FirstToUpper(err.Error()))
|
| 57 |
-
return false, err
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
b, err := json.Marshal(inputProver)
|
| 61 |
-
if err != nil {
|
| 62 |
-
err = fmt.Errorf("failed to serialize input prover, %w", err)
|
| 63 |
-
log.Error(FirstToUpper(err.Error()))
|
| 64 |
-
return false, err
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
proof.InputProver = string(b)
|
| 68 |
-
|
| 69 |
-
log.Infof("Sending a batch to the prover. OldStateRoot [%#x], OldBatchNum [%d]",
|
| 70 |
-
inputProver.PublicInputs.OldStateRoot, inputProver.PublicInputs.OldBatchNum)
|
| 71 |
-
|
| 72 |
-
genProofID, err = prover.BatchProof(inputProver)
|
| 73 |
-
if err != nil {
|
| 74 |
-
err = fmt.Errorf("failed to get batch proof id, %w", err)
|
| 75 |
-
log.Error(FirstToUpper(err.Error()))
|
| 76 |
-
return false, err
|
| 77 |
-
}
|
| 78 |
-
|
| 79 |
-
proof.ProofID = genProofID
|
| 80 |
-
|
| 81 |
-
log.Infof("Proof ID %v", *proof.ProofID)
|
| 82 |
-
log = log.WithFields("proofId", *proof.ProofID)
|
| 83 |
-
|
| 84 |
-
resGetProof, err := prover.WaitRecursiveProof(ctx, *proof.ProofID)
|
| 85 |
-
if err != nil {
|
| 86 |
-
err = fmt.Errorf("failed to get proof from prover, %w", err)
|
| 87 |
-
log.Error(FirstToUpper(err.Error()))
|
| 88 |
-
return false, err
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
log.Info("Batch proof generated")
|
| 92 |
-
|
| 93 |
-
proof.Proof = resGetProof
|
| 94 |
-
|
| 95 |
-
// NOTE(pg): the defer func is useless from now on, use a different variable
|
| 96 |
-
// name for errors (or shadow err in inner scopes) to not trigger it.
|
| 97 |
-
|
| 98 |
-
finalProofBuilt, finalProofErr := a.tryBuildFinalProof(ctx, prover, proof)
|
| 99 |
-
if finalProofErr != nil {
|
| 100 |
-
// just log the error and continue to handle the generated proof
|
| 101 |
-
log.Errorf("Error trying to build final proof: %v", finalProofErr)
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
// NOTE(pg): prover is done, use a.ctx from now on
|
| 105 |
-
|
| 106 |
-
if !finalProofBuilt {
|
| 107 |
-
proof.GeneratingSince = nil
|
| 108 |
-
|
| 109 |
-
// final proof has not been generated, update the batch proof
|
| 110 |
-
err := a.State.UpdateBatchProof(a.ctx, proof, nil)
|
| 111 |
-
if err != nil {
|
| 112 |
-
err = fmt.Errorf("failed to store batch proof result, %w", err)
|
| 113 |
-
log.Error(FirstToUpper(err.Error()))
|
| 114 |
-
return false, err
|
| 115 |
-
}
|
| 116 |
-
}
|
| 117 |
-
|
| 118 |
-
return true, nil
|
| 119 |
-
}
|
| 120 |
-
|
| 121 |
-
func (a *Aggregator) getAndLockBatchToProve(ctx context.Context, prover proverInterface) (*state.Batch, *state.Proof, error) {
|
| 122 |
-
proverID := prover.ID()
|
| 123 |
-
proverName := prover.Name()
|
| 124 |
-
|
| 125 |
-
log := log.WithFields(
|
| 126 |
-
"prover", proverName,
|
| 127 |
-
"proverId", proverID,
|
| 128 |
-
"proverAddr", prover.Addr(),
|
| 129 |
-
)
|
| 130 |
-
|
| 131 |
-
a.StateDBMutex.Lock()
|
| 132 |
-
defer a.StateDBMutex.Unlock()
|
| 133 |
-
|
| 134 |
-
lastVerifiedBatch, err := a.State.GetLastVerifiedBatch(ctx, nil)
|
| 135 |
-
if err != nil {
|
| 136 |
-
return nil, nil, err
|
| 137 |
-
}
|
| 138 |
-
|
| 139 |
-
// Get header of the last L1 block
|
| 140 |
-
lastL1BlockHeader, err := a.Ethman.GetLatestBlockHeader(ctx)
|
| 141 |
-
if err != nil {
|
| 142 |
-
log.Errorf("Failed to get last L1 block header, err: %v", err)
|
| 143 |
-
return nil, nil, err
|
| 144 |
-
}
|
| 145 |
-
lastL1BlockNumber := lastL1BlockHeader.Number.Uint64()
|
| 146 |
-
|
| 147 |
-
// Calculate max L1 block number for getting next virtual batch to prove
|
| 148 |
-
maxL1BlockNumber := uint64(0)
|
| 149 |
-
if a.cfg.BatchProofL1BlockConfirmations <= lastL1BlockNumber {
|
| 150 |
-
maxL1BlockNumber = lastL1BlockNumber - a.cfg.BatchProofL1BlockConfirmations
|
| 151 |
-
}
|
| 152 |
-
log.Debugf("Max L1 block number for getting next virtual batch to prove: %d", maxL1BlockNumber)
|
| 153 |
-
|
| 154 |
-
// Get virtual batch pending to generate proof
|
| 155 |
-
batchToVerify, err := a.State.GetVirtualBatchToProve(ctx, lastVerifiedBatch.BatchNumber, maxL1BlockNumber, nil)
|
| 156 |
-
if err != nil {
|
| 157 |
-
return nil, nil, err
|
| 158 |
-
}
|
| 159 |
-
|
| 160 |
-
log.Infof("Found virtual batch %d pending to generate proof", batchToVerify.BatchNumber)
|
| 161 |
-
log = log.WithFields("batch", batchToVerify.BatchNumber)
|
| 162 |
-
|
| 163 |
-
log.Info("Checking profitability to aggregate batch")
|
| 164 |
-
|
| 165 |
-
// pass pol collateral as zero here, bcs in smart contract fee for aggregator is not defined yet
|
| 166 |
-
isProfitable, err := a.ProfitabilityChecker.IsProfitable(ctx, big.NewInt(0))
|
| 167 |
-
if err != nil {
|
| 168 |
-
log.Errorf("Failed to check aggregator profitability, err: %v", err)
|
| 169 |
-
return nil, nil, err
|
| 170 |
-
}
|
| 171 |
-
|
| 172 |
-
if !isProfitable {
|
| 173 |
-
log.Infof("Batch is not profitable, pol collateral %d", big.NewInt(0))
|
| 174 |
-
return nil, nil, err
|
| 175 |
-
}
|
| 176 |
-
|
| 177 |
-
now := time.Now().Round(time.Microsecond)
|
| 178 |
-
proof := &state.Proof{
|
| 179 |
-
BatchNumber: batchToVerify.BatchNumber,
|
| 180 |
-
BatchNumberFinal: batchToVerify.BatchNumber,
|
| 181 |
-
Prover: &proverName,
|
| 182 |
-
ProverID: &proverID,
|
| 183 |
-
GeneratingSince: &now,
|
| 184 |
-
}
|
| 185 |
-
|
| 186 |
-
// Avoid other prover to process the same batch
|
| 187 |
-
err = a.State.AddBatchProof(ctx, proof, nil)
|
| 188 |
-
if err != nil {
|
| 189 |
-
log.Errorf("Failed to add batch proof, err: %v", err)
|
| 190 |
-
return nil, nil, err
|
| 191 |
-
}
|
| 192 |
-
|
| 193 |
-
return batchToVerify, proof, nil
|
| 194 |
-
}
|
| 195 |
-
|
| 196 |
-
func (a *Aggregator) tryAggregateBatchProofs(ctx context.Context, prover proverInterface) (bool, error) {
|
| 197 |
-
proverName := prover.Name()
|
| 198 |
-
proverID := prover.ID()
|
| 199 |
-
|
| 200 |
-
log := log.WithFields(
|
| 201 |
-
"prover", proverName,
|
| 202 |
-
"proverId", proverID,
|
| 203 |
-
"proverAddr", prover.Addr(),
|
| 204 |
-
)
|
| 205 |
-
log.Debug("tryAggregateProofs start")
|
| 206 |
-
|
| 207 |
-
proof1, proof2, err0 := a.getAndLockBatchProofsToAggregate(ctx, prover)
|
| 208 |
-
if errors.Is(err0, state.ErrNotFound) {
|
| 209 |
-
// nothing to aggregate, swallow the error
|
| 210 |
-
log.Debug("Nothing to aggregate")
|
| 211 |
-
return false, nil
|
| 212 |
-
}
|
| 213 |
-
if err0 != nil {
|
| 214 |
-
return false, err0
|
| 215 |
-
}
|
| 216 |
-
|
| 217 |
-
var (
|
| 218 |
-
aggrProofID *string
|
| 219 |
-
err error
|
| 220 |
-
)
|
| 221 |
-
|
| 222 |
-
defer func() {
|
| 223 |
-
if err != nil {
|
| 224 |
-
err2 := a.unlockBatchProofsToAggregate(a.ctx, proof1, proof2)
|
| 225 |
-
if err2 != nil {
|
| 226 |
-
log.Errorf("Failed to release aggregated proofs, err: %v", err2)
|
| 227 |
-
}
|
| 228 |
-
}
|
| 229 |
-
log.Debug("tryAggregateProofs end")
|
| 230 |
-
}()
|
| 231 |
-
|
| 232 |
-
log.Infof("Aggregating proofs: %d-%d and %d-%d", proof1.BatchNumber, proof1.BatchNumberFinal, proof2.BatchNumber, proof2.BatchNumberFinal)
|
| 233 |
-
|
| 234 |
-
batches := fmt.Sprintf("%d-%d", proof1.BatchNumber, proof2.BatchNumberFinal)
|
| 235 |
-
log = log.WithFields("batches", batches)
|
| 236 |
-
|
| 237 |
-
inputProver := map[string]interface{}{
|
| 238 |
-
"recursive_proof_1": proof1.Proof,
|
| 239 |
-
"recursive_proof_2": proof2.Proof,
|
| 240 |
-
}
|
| 241 |
-
b, err := json.Marshal(inputProver)
|
| 242 |
-
if err != nil {
|
| 243 |
-
err = fmt.Errorf("failed to serialize input prover, %w", err)
|
| 244 |
-
log.Error(FirstToUpper(err.Error()))
|
| 245 |
-
return false, err
|
| 246 |
-
}
|
| 247 |
-
|
| 248 |
-
proof := &state.Proof{
|
| 249 |
-
BatchNumber: proof1.BatchNumber,
|
| 250 |
-
BatchNumberFinal: proof2.BatchNumberFinal,
|
| 251 |
-
Prover: &proverName,
|
| 252 |
-
ProverID: &proverID,
|
| 253 |
-
InputProver: string(b),
|
| 254 |
-
}
|
| 255 |
-
|
| 256 |
-
aggrProofID, err = prover.AggregatedProof(proof1.Proof, proof2.Proof)
|
| 257 |
-
if err != nil {
|
| 258 |
-
err = fmt.Errorf("failed to get aggregated proof id, %w", err)
|
| 259 |
-
log.Error(FirstToUpper(err.Error()))
|
| 260 |
-
return false, err
|
| 261 |
-
}
|
| 262 |
-
|
| 263 |
-
proof.ProofID = aggrProofID
|
| 264 |
-
|
| 265 |
-
log.Infof("Proof ID for aggregated proof: %v", *proof.ProofID)
|
| 266 |
-
log = log.WithFields("proofId", *proof.ProofID)
|
| 267 |
-
|
| 268 |
-
recursiveProof, err := prover.WaitRecursiveProof(ctx, *proof.ProofID)
|
| 269 |
-
if err != nil {
|
| 270 |
-
err = fmt.Errorf("failed to get aggregated proof from prover, %w", err)
|
| 271 |
-
log.Error(FirstToUpper(err.Error()))
|
| 272 |
-
return false, err
|
| 273 |
-
}
|
| 274 |
-
|
| 275 |
-
log.Info("Aggregated proof generated")
|
| 276 |
-
|
| 277 |
-
proof.Proof = recursiveProof
|
| 278 |
-
|
| 279 |
-
// update the state by removing the 2 aggregated proofs and storing the
|
| 280 |
-
// newly generated recursive proof
|
| 281 |
-
dbTx, err := a.State.BeginStateTransaction(ctx)
|
| 282 |
-
if err != nil {
|
| 283 |
-
err = fmt.Errorf("failed to begin transaction to update proof aggregation state, %w", err)
|
| 284 |
-
log.Error(FirstToUpper(err.Error()))
|
| 285 |
-
return false, err
|
| 286 |
-
}
|
| 287 |
-
|
| 288 |
-
err = a.State.DeleteBatchProofs(ctx, proof1.BatchNumber, proof2.BatchNumberFinal, dbTx)
|
| 289 |
-
if err != nil {
|
| 290 |
-
if err := dbTx.Rollback(ctx); err != nil {
|
| 291 |
-
err := fmt.Errorf("failed to rollback proof aggregation state, %w", err)
|
| 292 |
-
log.Error(FirstToUpper(err.Error()))
|
| 293 |
-
return false, err
|
| 294 |
-
}
|
| 295 |
-
err = fmt.Errorf("failed to delete previously aggregated proofs, %w", err)
|
| 296 |
-
log.Error(FirstToUpper(err.Error()))
|
| 297 |
-
return false, err
|
| 298 |
-
}
|
| 299 |
-
|
| 300 |
-
now := time.Now().Round(time.Microsecond)
|
| 301 |
-
proof.GeneratingSince = &now
|
| 302 |
-
|
| 303 |
-
err = a.State.AddBatchProof(ctx, proof, dbTx)
|
| 304 |
-
if err != nil {
|
| 305 |
-
if err := dbTx.Rollback(ctx); err != nil {
|
| 306 |
-
err := fmt.Errorf("failed to rollback proof aggregation state, %w", err)
|
| 307 |
-
log.Error(FirstToUpper(err.Error()))
|
| 308 |
-
return false, err
|
| 309 |
-
}
|
| 310 |
-
err = fmt.Errorf("failed to store the recursive proof, %w", err)
|
| 311 |
-
log.Error(FirstToUpper(err.Error()))
|
| 312 |
-
return false, err
|
| 313 |
-
}
|
| 314 |
-
|
| 315 |
-
err = dbTx.Commit(ctx)
|
| 316 |
-
if err != nil {
|
| 317 |
-
err = fmt.Errorf("failed to store the recursive proof, %w", err)
|
| 318 |
-
log.Error(FirstToUpper(err.Error()))
|
| 319 |
-
return false, err
|
| 320 |
-
}
|
| 321 |
-
|
| 322 |
-
// The defer func is useless from now on, use a different variable
|
| 323 |
-
// name for errors (or shadow err in inner scopes) to not trigger it.
|
| 324 |
-
|
| 325 |
-
// state is up to date, check if we can send the final proof using the
|
| 326 |
-
// one just crafted.
|
| 327 |
-
finalProofBuilt, finalProofErr := a.tryBuildFinalProof(ctx, prover, proof)
|
| 328 |
-
if finalProofErr != nil {
|
| 329 |
-
// just log the error and continue to handle the aggregated proof
|
| 330 |
-
log.Errorf("Failed trying to check if recursive proof can be verified: %v", finalProofErr)
|
| 331 |
-
}
|
| 332 |
-
|
| 333 |
-
// Prover is done, use a.ctx from now on
|
| 334 |
-
|
| 335 |
-
if !finalProofBuilt {
|
| 336 |
-
proof.GeneratingSince = nil
|
| 337 |
-
|
| 338 |
-
// final proof has not been generated, update the recursive proof
|
| 339 |
-
err := a.State.UpdateBatchProof(a.ctx, proof, nil)
|
| 340 |
-
if err != nil {
|
| 341 |
-
err = fmt.Errorf("failed to store batch proof result, %w", err)
|
| 342 |
-
log.Error(FirstToUpper(err.Error()))
|
| 343 |
-
return false, err
|
| 344 |
-
}
|
| 345 |
-
}
|
| 346 |
-
|
| 347 |
-
return true, nil
|
| 348 |
-
}
|
| 349 |
-
|
| 350 |
-
func (a *Aggregator) getAndLockBatchProofsToAggregate(ctx context.Context, prover proverInterface) (*state.Proof, *state.Proof, error) {
|
| 351 |
-
log := log.WithFields(
|
| 352 |
-
"prover", prover.Name(),
|
| 353 |
-
"proverId", prover.ID(),
|
| 354 |
-
"proverAddr", prover.Addr(),
|
| 355 |
-
)
|
| 356 |
-
|
| 357 |
-
a.StateDBMutex.Lock()
|
| 358 |
-
defer a.StateDBMutex.Unlock()
|
| 359 |
-
|
| 360 |
-
proof1, proof2, err := a.State.GetBatchProofsToAggregate(ctx, nil)
|
| 361 |
-
if err != nil {
|
| 362 |
-
return nil, nil, err
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
// Set proofs in generating state in a single transaction
|
| 366 |
-
dbTx, err := a.State.BeginStateTransaction(ctx)
|
| 367 |
-
if err != nil {
|
| 368 |
-
log.Errorf("Failed to begin transaction to set proof aggregation state, err: %v", err)
|
| 369 |
-
return nil, nil, err
|
| 370 |
-
}
|
| 371 |
-
|
| 372 |
-
now := time.Now().Round(time.Microsecond)
|
| 373 |
-
proof1.GeneratingSince = &now
|
| 374 |
-
err = a.State.UpdateBatchProof(ctx, proof1, dbTx)
|
| 375 |
-
if err == nil {
|
| 376 |
-
proof2.GeneratingSince = &now
|
| 377 |
-
err = a.State.UpdateBatchProof(ctx, proof2, dbTx)
|
| 378 |
-
}
|
| 379 |
-
|
| 380 |
-
if err != nil {
|
| 381 |
-
if err := dbTx.Rollback(ctx); err != nil {
|
| 382 |
-
err := fmt.Errorf("failed to rollback proof aggregation state %w", err)
|
| 383 |
-
log.Error(FirstToUpper(err.Error()))
|
| 384 |
-
return nil, nil, err
|
| 385 |
-
}
|
| 386 |
-
return nil, nil, fmt.Errorf("failed to set proof aggregation state %w", err)
|
| 387 |
-
}
|
| 388 |
-
|
| 389 |
-
err = dbTx.Commit(ctx)
|
| 390 |
-
if err != nil {
|
| 391 |
-
return nil, nil, fmt.Errorf("failed to set proof aggregation state %w", err)
|
| 392 |
-
}
|
| 393 |
-
|
| 394 |
-
return proof1, proof2, nil
|
| 395 |
-
}
|
| 396 |
-
|
| 397 |
-
func (a *Aggregator) unlockBatchProofsToAggregate(ctx context.Context, proof1 *state.Proof, proof2 *state.Proof) error {
|
| 398 |
-
// Release proofs from generating state in a single transaction
|
| 399 |
-
dbTx, err := a.State.BeginStateTransaction(ctx)
|
| 400 |
-
if err != nil {
|
| 401 |
-
log.Warnf("Failed to begin transaction to release proof aggregation state, err: %v", err)
|
| 402 |
-
return err
|
| 403 |
-
}
|
| 404 |
-
|
| 405 |
-
proof1.GeneratingSince = nil
|
| 406 |
-
err = a.State.UpdateBatchProof(ctx, proof1, dbTx)
|
| 407 |
-
if err == nil {
|
| 408 |
-
proof2.GeneratingSince = nil
|
| 409 |
-
err = a.State.UpdateBatchProof(ctx, proof2, dbTx)
|
| 410 |
-
}
|
| 411 |
-
|
| 412 |
-
if err != nil {
|
| 413 |
-
if err := dbTx.Rollback(ctx); err != nil {
|
| 414 |
-
err := fmt.Errorf("failed to rollback proof aggregation state: %w", err)
|
| 415 |
-
log.Error(FirstToUpper(err.Error()))
|
| 416 |
-
return err
|
| 417 |
-
}
|
| 418 |
-
return fmt.Errorf("failed to release proof aggregation state: %w", err)
|
| 419 |
-
}
|
| 420 |
-
|
| 421 |
-
err = dbTx.Commit(ctx)
|
| 422 |
-
if err != nil {
|
| 423 |
-
return fmt.Errorf("failed to release proof aggregation state %w", err)
|
| 424 |
-
}
|
| 425 |
-
|
| 426 |
-
return nil
|
| 427 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,7 +0,0 @@
|
|
| 1 |
-
package aggregator
|
| 2 |
-
|
| 3 |
-
import "context"
|
| 4 |
-
|
| 5 |
-
func (a *Aggregator) tryGenerateBlobInnerProof(ctx context.Context, prover proverInterface) (bool, error) {
|
| 6 |
-
return false, nil
|
| 7 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,11 +0,0 @@
|
|
| 1 |
-
package aggregator
|
| 2 |
-
|
| 3 |
-
import "context"
|
| 4 |
-
|
| 5 |
-
func (a *Aggregator) tryGenerateBlobOuterProof(ctx context.Context, prover proverInterface) (bool, error) {
|
| 6 |
-
return false, nil
|
| 7 |
-
}
|
| 8 |
-
|
| 9 |
-
func (a *Aggregator) tryAggregateBlobOuterProofs(ctx context.Context, prover proverInterface) (bool, error) {
|
| 10 |
-
return false, nil
|
| 11 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -8,6 +8,17 @@
|
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/encoding"
|
| 9 |
)
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
// TokenAmountWithDecimals is a wrapper type that parses token amount with decimals to big int
|
| 12 |
type TokenAmountWithDecimals struct {
|
| 13 |
*big.Int `validate:"required"`
|
|
@@ -89,6 +100,18 @@
|
|
| 89 |
// UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog
|
| 90 |
UpgradeEtrogBatchNumber uint64 `mapstructure:"UpgradeEtrogBatchNumber"`
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
// BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch
|
| 93 |
BatchProofL1BlockConfirmations uint64 `mapstructure:"BatchProofL1BlockConfirmations"`
|
| 94 |
}
|
|
|
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/encoding"
|
| 9 |
)
|
| 10 |
|
| 11 |
+
// SettlementBackend is the type of the settlement backend
|
| 12 |
+
type SettlementBackend string
|
| 13 |
+
|
| 14 |
+
const (
|
| 15 |
+
// AggLayer settlement backend
|
| 16 |
+
AggLayer SettlementBackend = "agglayer"
|
| 17 |
+
|
| 18 |
+
// L1 settlement backend
|
| 19 |
+
L1 SettlementBackend = "l1"
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
// TokenAmountWithDecimals is a wrapper type that parses token amount with decimals to big int
|
| 23 |
type TokenAmountWithDecimals struct {
|
| 24 |
*big.Int `validate:"required"`
|
|
|
|
| 100 |
// UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog
|
| 101 |
UpgradeEtrogBatchNumber uint64 `mapstructure:"UpgradeEtrogBatchNumber"`
|
| 102 |
|
| 103 |
+
// SettlementBackend configuration defines how a final ZKP should be settled. Directly to L1 or over the Beethoven service.
|
| 104 |
+
SettlementBackend SettlementBackend `mapstructure:"SettlementBackend"`
|
| 105 |
+
|
| 106 |
+
// AggLayerTxTimeout is the interval time to wait for a tx to be mined from the agglayer
|
| 107 |
+
AggLayerTxTimeout types.Duration `mapstructure:"AggLayerTxTimeout"`
|
| 108 |
+
|
| 109 |
+
// AggLayerURL url of the agglayer service
|
| 110 |
+
AggLayerURL string `mapstructure:"AggLayerURL"`
|
| 111 |
+
|
| 112 |
+
// SequencerPrivateKey Private key of the trusted sequencer
|
| 113 |
+
SequencerPrivateKey types.KeystoreFileConfig `mapstructure:"SequencerPrivateKey"`
|
| 114 |
+
|
| 115 |
// BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch
|
| 116 |
BatchProofL1BlockConfirmations uint64 `mapstructure:"BatchProofL1BlockConfirmations"`
|
| 117 |
}
|
|
@@ -1,288 +0,0 @@
|
|
| 1 |
-
package aggregator
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
"fmt"
|
| 7 |
-
"time"
|
| 8 |
-
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/aggregator/prover"
|
| 10 |
-
ethmanTypes "github.com/0xPolygonHermez/zkevm-node/etherman/types"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/ethtxmanager"
|
| 12 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 13 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 14 |
-
"github.com/ethereum/go-ethereum/common"
|
| 15 |
-
"github.com/jackc/pgx/v4"
|
| 16 |
-
)
|
| 17 |
-
|
| 18 |
-
// tryBuildFinalProof checks if the provided proof is eligible to be used to
|
| 19 |
-
// build the final proof. If no proof is provided it looks for a previously
|
| 20 |
-
// generated proof. If the proof is eligible, then the final proof generation
|
| 21 |
-
// is triggered.
|
| 22 |
-
func (a *Aggregator) tryBuildFinalProof(ctx context.Context, prover proverInterface, proof *state.Proof) (bool, error) {
|
| 23 |
-
proverName := prover.Name()
|
| 24 |
-
proverID := prover.ID()
|
| 25 |
-
|
| 26 |
-
log := log.WithFields(
|
| 27 |
-
"prover", proverName,
|
| 28 |
-
"proverId", proverID,
|
| 29 |
-
"proverAddr", prover.Addr(),
|
| 30 |
-
)
|
| 31 |
-
log.Debug("tryBuildFinalProof start")
|
| 32 |
-
|
| 33 |
-
var err error
|
| 34 |
-
if !a.canVerifyProof() {
|
| 35 |
-
log.Debug("Time to verify proof not reached or proof verification in progress")
|
| 36 |
-
return false, nil
|
| 37 |
-
}
|
| 38 |
-
log.Debug("Send final proof time reached")
|
| 39 |
-
|
| 40 |
-
for !a.isSynced(ctx, nil) {
|
| 41 |
-
log.Info("Waiting for synchronizer to sync...")
|
| 42 |
-
time.Sleep(a.cfg.RetryTime.Duration)
|
| 43 |
-
continue
|
| 44 |
-
}
|
| 45 |
-
|
| 46 |
-
var lastVerifiedBatchNum uint64
|
| 47 |
-
lastVerifiedBatch, err := a.State.GetLastVerifiedBatch(ctx, nil)
|
| 48 |
-
if err != nil && !errors.Is(err, state.ErrNotFound) {
|
| 49 |
-
return false, fmt.Errorf("failed to get last verified batch, %w", err)
|
| 50 |
-
}
|
| 51 |
-
if lastVerifiedBatch != nil {
|
| 52 |
-
lastVerifiedBatchNum = lastVerifiedBatch.BatchNumber
|
| 53 |
-
}
|
| 54 |
-
|
| 55 |
-
if proof == nil {
|
| 56 |
-
// we don't have a proof generating at the moment, check if we
|
| 57 |
-
// have a proof ready to verify
|
| 58 |
-
|
| 59 |
-
proof, err = a.getAndLockProofReadyForFinal(ctx, prover, lastVerifiedBatchNum)
|
| 60 |
-
if errors.Is(err, state.ErrNotFound) {
|
| 61 |
-
// nothing to verify, swallow the error
|
| 62 |
-
log.Debug("No proof ready to verify")
|
| 63 |
-
return false, nil
|
| 64 |
-
}
|
| 65 |
-
if err != nil {
|
| 66 |
-
return false, err
|
| 67 |
-
}
|
| 68 |
-
|
| 69 |
-
defer func() {
|
| 70 |
-
if err != nil {
|
| 71 |
-
// Set the generating state to false for the proof ("unlock" it)
|
| 72 |
-
proof.GeneratingSince = nil
|
| 73 |
-
err2 := a.State.UpdateBatchProof(a.ctx, proof, nil)
|
| 74 |
-
if err2 != nil {
|
| 75 |
-
log.Errorf("Failed to unlock proof: %v", err2)
|
| 76 |
-
}
|
| 77 |
-
}
|
| 78 |
-
}()
|
| 79 |
-
} else {
|
| 80 |
-
// we do have a proof generating at the moment, check if it is
|
| 81 |
-
// eligible to be verified
|
| 82 |
-
eligible, err := a.validateEligibleFinalProof(ctx, proof, lastVerifiedBatchNum)
|
| 83 |
-
if err != nil {
|
| 84 |
-
return false, fmt.Errorf("failed to validate eligible final proof, %w", err)
|
| 85 |
-
}
|
| 86 |
-
if !eligible {
|
| 87 |
-
return false, nil
|
| 88 |
-
}
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
log = log.WithFields(
|
| 92 |
-
"proofId", *proof.ProofID,
|
| 93 |
-
"batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal),
|
| 94 |
-
)
|
| 95 |
-
|
| 96 |
-
// at this point we have an eligible proof, build the final one using it
|
| 97 |
-
finalProof, err := a.buildFinalProof(ctx, prover, proof)
|
| 98 |
-
if err != nil {
|
| 99 |
-
err = fmt.Errorf("failed to build final proof, %w", err)
|
| 100 |
-
log.Error(FirstToUpper(err.Error()))
|
| 101 |
-
return false, err
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
msg := finalProofMsg{
|
| 105 |
-
proverName: proverName,
|
| 106 |
-
proverID: proverID,
|
| 107 |
-
recursiveProof: proof,
|
| 108 |
-
finalProof: finalProof,
|
| 109 |
-
}
|
| 110 |
-
|
| 111 |
-
select {
|
| 112 |
-
case <-a.ctx.Done():
|
| 113 |
-
return false, a.ctx.Err()
|
| 114 |
-
case a.finalProof <- msg:
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
log.Debug("tryBuildFinalProof end")
|
| 118 |
-
return true, nil
|
| 119 |
-
}
|
| 120 |
-
|
| 121 |
-
// buildFinalProof builds and return the final proof for an aggregated/batch proof.
|
| 122 |
-
func (a *Aggregator) buildFinalProof(ctx context.Context, prover proverInterface, proof *state.Proof) (*prover.FinalProof, error) {
|
| 123 |
-
log := log.WithFields(
|
| 124 |
-
"prover", prover.Name(),
|
| 125 |
-
"proverId", prover.ID(),
|
| 126 |
-
"proverAddr", prover.Addr(),
|
| 127 |
-
"recursiveProofId", *proof.ProofID,
|
| 128 |
-
"batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal),
|
| 129 |
-
)
|
| 130 |
-
log.Info("Generating final proof")
|
| 131 |
-
|
| 132 |
-
finalProofID, err := prover.FinalProof(proof.Proof, a.cfg.SenderAddress)
|
| 133 |
-
if err != nil {
|
| 134 |
-
return nil, fmt.Errorf("failed to get final proof id: %w", err)
|
| 135 |
-
}
|
| 136 |
-
proof.ProofID = finalProofID
|
| 137 |
-
|
| 138 |
-
log.Infof("Final proof ID for batches [%d-%d]: %s", proof.BatchNumber, proof.BatchNumberFinal, *proof.ProofID)
|
| 139 |
-
log = log.WithFields("finalProofId", finalProofID)
|
| 140 |
-
|
| 141 |
-
finalProof, err := prover.WaitFinalProof(ctx, *proof.ProofID)
|
| 142 |
-
if err != nil {
|
| 143 |
-
return nil, fmt.Errorf("failed to get final proof from prover: %w", err)
|
| 144 |
-
}
|
| 145 |
-
|
| 146 |
-
log.Info("Final proof generated")
|
| 147 |
-
|
| 148 |
-
// mock prover sanity check
|
| 149 |
-
if string(finalProof.Public.NewStateRoot) == mockedStateRoot && string(finalProof.Public.NewLocalExitRoot) == mockedLocalExitRoot {
|
| 150 |
-
// This local exit root and state root come from the mock
|
| 151 |
-
// prover, use the one captured by the executor instead
|
| 152 |
-
finalBatch, err := a.State.GetBatchByNumber(ctx, proof.BatchNumberFinal, nil)
|
| 153 |
-
if err != nil {
|
| 154 |
-
return nil, fmt.Errorf("failed to retrieve batch with number [%d]", proof.BatchNumberFinal)
|
| 155 |
-
}
|
| 156 |
-
log.Warnf("NewLocalExitRoot and NewStateRoot look like a mock values, using values from executor instead: LER: %v, SR: %v",
|
| 157 |
-
finalBatch.LocalExitRoot.TerminalString(), finalBatch.StateRoot.TerminalString())
|
| 158 |
-
finalProof.Public.NewStateRoot = finalBatch.StateRoot.Bytes()
|
| 159 |
-
finalProof.Public.NewLocalExitRoot = finalBatch.LocalExitRoot.Bytes()
|
| 160 |
-
}
|
| 161 |
-
|
| 162 |
-
return finalProof, nil
|
| 163 |
-
}
|
| 164 |
-
|
| 165 |
-
func (a *Aggregator) getAndLockProofReadyForFinal(ctx context.Context, prover proverInterface, lastVerifiedBatchNum uint64) (*state.Proof, error) {
|
| 166 |
-
a.StateDBMutex.Lock()
|
| 167 |
-
defer a.StateDBMutex.Unlock()
|
| 168 |
-
|
| 169 |
-
// Get proof ready to be verified
|
| 170 |
-
proofToVerify, err := a.State.GetProofReadyForFinal(ctx, lastVerifiedBatchNum, nil)
|
| 171 |
-
if err != nil {
|
| 172 |
-
return nil, err
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
now := time.Now().Round(time.Microsecond)
|
| 176 |
-
proofToVerify.GeneratingSince = &now
|
| 177 |
-
|
| 178 |
-
err = a.State.UpdateBatchProof(ctx, proofToVerify, nil)
|
| 179 |
-
if err != nil {
|
| 180 |
-
return nil, err
|
| 181 |
-
}
|
| 182 |
-
|
| 183 |
-
return proofToVerify, nil
|
| 184 |
-
}
|
| 185 |
-
|
| 186 |
-
func (a *Aggregator) validateEligibleFinalProof(ctx context.Context, proof *state.Proof, lastVerifiedBatchNum uint64) (bool, error) {
|
| 187 |
-
batchNumberToVerify := lastVerifiedBatchNum + 1
|
| 188 |
-
|
| 189 |
-
if proof.BatchNumber != batchNumberToVerify {
|
| 190 |
-
if proof.BatchNumber < batchNumberToVerify && proof.BatchNumberFinal >= batchNumberToVerify {
|
| 191 |
-
// We have a proof that contains some batches below the last batch verified, anyway can be eligible as final proof
|
| 192 |
-
log.Warnf("Proof %d-%d contains some batches lower than last batch verified %d. Check anyway if it is eligible", proof.BatchNumber, proof.BatchNumberFinal, lastVerifiedBatchNum)
|
| 193 |
-
} else if proof.BatchNumberFinal < batchNumberToVerify {
|
| 194 |
-
// We have a proof that contains batches below that the last batch verified, we need to delete this proof
|
| 195 |
-
log.Warnf("Proof %d-%d lower than next batch to verify %d. Deleting it", proof.BatchNumber, proof.BatchNumberFinal, batchNumberToVerify)
|
| 196 |
-
err := a.State.DeleteBatchProofs(ctx, proof.BatchNumber, proof.BatchNumberFinal, nil)
|
| 197 |
-
if err != nil {
|
| 198 |
-
return false, fmt.Errorf("failed to delete discarded proof, err: %w", err)
|
| 199 |
-
}
|
| 200 |
-
return false, nil
|
| 201 |
-
} else {
|
| 202 |
-
log.Debugf("Proof batch number %d is not the following to last verfied batch number %d", proof.BatchNumber, lastVerifiedBatchNum)
|
| 203 |
-
return false, nil
|
| 204 |
-
}
|
| 205 |
-
}
|
| 206 |
-
|
| 207 |
-
bComplete, err := a.State.CheckProofContainsCompleteSequences(ctx, proof, nil)
|
| 208 |
-
if err != nil {
|
| 209 |
-
return false, fmt.Errorf("failed to check if proof contains complete sequences, %w", err)
|
| 210 |
-
}
|
| 211 |
-
if !bComplete {
|
| 212 |
-
log.Infof("Recursive proof %d-%d not eligible to be verified: not containing complete sequences", proof.BatchNumber, proof.BatchNumberFinal)
|
| 213 |
-
return false, nil
|
| 214 |
-
}
|
| 215 |
-
return true, nil
|
| 216 |
-
}
|
| 217 |
-
|
| 218 |
-
// This function waits to receive a final proof from a prover. Once it receives
|
| 219 |
-
// the proof, it performs these steps in order:
|
| 220 |
-
// - send the final proof to L1
|
| 221 |
-
// - wait for the synchronizer to catch up
|
| 222 |
-
// - clean up the cache of recursive proofs
|
| 223 |
-
func (a *Aggregator) sendFinalProof() {
|
| 224 |
-
for {
|
| 225 |
-
select {
|
| 226 |
-
case <-a.ctx.Done():
|
| 227 |
-
return
|
| 228 |
-
case msg := <-a.finalProof:
|
| 229 |
-
ctx := a.ctx
|
| 230 |
-
proof := msg.recursiveProof
|
| 231 |
-
|
| 232 |
-
log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 233 |
-
log.Info("Verifying final proof with ethereum smart contract")
|
| 234 |
-
|
| 235 |
-
a.startProofVerification()
|
| 236 |
-
|
| 237 |
-
finalBatch, err := a.State.GetBatchByNumber(ctx, proof.BatchNumberFinal, nil)
|
| 238 |
-
if err != nil {
|
| 239 |
-
log.Errorf("Failed to retrieve batch with number [%d]: %v", proof.BatchNumberFinal, err)
|
| 240 |
-
a.endProofVerification()
|
| 241 |
-
continue
|
| 242 |
-
}
|
| 243 |
-
|
| 244 |
-
inputs := ethmanTypes.FinalProofInputs{
|
| 245 |
-
FinalProof: msg.finalProof,
|
| 246 |
-
NewLocalExitRoot: finalBatch.LocalExitRoot.Bytes(),
|
| 247 |
-
NewStateRoot: finalBatch.StateRoot.Bytes(),
|
| 248 |
-
}
|
| 249 |
-
|
| 250 |
-
log.Infof("Final proof inputs: NewLocalExitRoot [%#x], NewStateRoot [%#x]", inputs.NewLocalExitRoot, inputs.NewStateRoot)
|
| 251 |
-
|
| 252 |
-
// add batch verification to be monitored
|
| 253 |
-
sender := common.HexToAddress(a.cfg.SenderAddress)
|
| 254 |
-
to, data, err := a.Ethman.BuildTrustedVerifyBatchesTxData(proof.BatchNumber-1, proof.BatchNumberFinal, &inputs, sender)
|
| 255 |
-
if err != nil {
|
| 256 |
-
log.Errorf("Error estimating batch verification to add to eth tx manager: %v", err)
|
| 257 |
-
a.handleErrorSendFinalProof(ctx, proof)
|
| 258 |
-
continue
|
| 259 |
-
}
|
| 260 |
-
monitoredTxID := buildMonitoredTxID(proof.BatchNumber, proof.BatchNumberFinal)
|
| 261 |
-
err = a.EthTxManager.Add(ctx, ethTxManagerOwner, monitoredTxID, sender, to, nil, data, a.cfg.GasOffset, nil)
|
| 262 |
-
if err != nil {
|
| 263 |
-
mTxLogger := ethtxmanager.CreateLogger(ethTxManagerOwner, monitoredTxID, sender, to)
|
| 264 |
-
mTxLogger.Errorf("Error to add batch verification tx to eth tx manager: %v", err)
|
| 265 |
-
a.handleErrorSendFinalProof(ctx, proof)
|
| 266 |
-
continue
|
| 267 |
-
}
|
| 268 |
-
|
| 269 |
-
// process monitored batch verifications before starting a next cycle
|
| 270 |
-
a.EthTxManager.ProcessPendingMonitoredTxs(ctx, ethTxManagerOwner, func(result ethtxmanager.MonitoredTxResult, dbTx pgx.Tx) {
|
| 271 |
-
a.handleMonitoredTxResult(result)
|
| 272 |
-
}, nil)
|
| 273 |
-
|
| 274 |
-
a.resetVerifyProofTime()
|
| 275 |
-
a.endProofVerification()
|
| 276 |
-
}
|
| 277 |
-
}
|
| 278 |
-
}
|
| 279 |
-
|
| 280 |
-
func (a *Aggregator) handleErrorSendFinalProof(ctx context.Context, proof *state.Proof) {
|
| 281 |
-
log := log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 282 |
-
proof.GeneratingSince = nil
|
| 283 |
-
err := a.State.UpdateBatchProof(ctx, proof, nil)
|
| 284 |
-
if err != nil {
|
| 285 |
-
log.Errorf("Failed updating proof state (false): %v", err)
|
| 286 |
-
}
|
| 287 |
-
a.endProofVerification()
|
| 288 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -38,6 +38,7 @@
|
|
| 38 |
|
| 39 |
// etherman contains the methods required to interact with ethereum
|
| 40 |
type etherman interface {
|
|
|
|
| 41 |
GetLatestVerifiedBatchNum() (uint64, error)
|
| 42 |
BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, inputs *ethmanTypes.FinalProofInputs, beneficiary common.Address) (to *common.Address, data []byte, err error)
|
| 43 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
|
@@ -54,16 +55,16 @@
|
|
| 54 |
BeginStateTransaction(ctx context.Context) (pgx.Tx, error)
|
| 55 |
CheckProofContainsCompleteSequences(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) (bool, error)
|
| 56 |
GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
| 57 |
-
|
| 58 |
GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 59 |
-
|
| 60 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 68 |
GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error)
|
| 69 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
|
|
|
| 38 |
|
| 39 |
// etherman contains the methods required to interact with ethereum
|
| 40 |
type etherman interface {
|
| 41 |
+
GetRollupId() uint32
|
| 42 |
GetLatestVerifiedBatchNum() (uint64, error)
|
| 43 |
BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, inputs *ethmanTypes.FinalProofInputs, beneficiary common.Address) (to *common.Address, data []byte, err error)
|
| 44 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
|
|
|
| 55 |
BeginStateTransaction(ctx context.Context) (pgx.Tx, error)
|
| 56 |
CheckProofContainsCompleteSequences(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) (bool, error)
|
| 57 |
GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
| 58 |
+
GetProofReadyToVerify(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Proof, error)
|
| 59 |
GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 60 |
+
GetProofsToAggregate(ctx context.Context, dbTx pgx.Tx) (*state.Proof, *state.Proof, error)
|
| 61 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 62 |
+
AddGeneratedProof(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) error
|
| 63 |
+
UpdateGeneratedProof(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) error
|
| 64 |
+
DeleteGeneratedProofs(ctx context.Context, batchNumber uint64, batchNumberFinal uint64, dbTx pgx.Tx) error
|
| 65 |
+
DeleteUngeneratedProofs(ctx context.Context, dbTx pgx.Tx) error
|
| 66 |
+
CleanupGeneratedProofs(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
| 67 |
+
CleanupLockedProofs(ctx context.Context, duration string, dbTx pgx.Tx) (int64, error)
|
| 68 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 69 |
GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error)
|
| 70 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
|
@@ -1,68 +0,0 @@
|
|
| 1 |
-
//go:generate oapi-codegen -package=examplepkg -generate=types,client,spec -o=examplepkg/example-client.go beacon-node-oapi.json
|
| 2 |
-
package beaconclient
|
| 3 |
-
|
| 4 |
-
import (
|
| 5 |
-
"context"
|
| 6 |
-
"encoding/json"
|
| 7 |
-
"fmt"
|
| 8 |
-
"io"
|
| 9 |
-
"net/http"
|
| 10 |
-
)
|
| 11 |
-
|
| 12 |
-
// BeaconAPIClient client of Beacon API
|
| 13 |
-
// https://ethereum.github.io/beacon-APIs/
|
| 14 |
-
type BeaconAPIClient struct {
|
| 15 |
-
urlBase string
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
// NewBeaconAPIClient creates an instance of client
|
| 19 |
-
func NewBeaconAPIClient(url string) *BeaconAPIClient {
|
| 20 |
-
return &BeaconAPIClient{
|
| 21 |
-
urlBase: url,
|
| 22 |
-
}
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
// BeaconAPIResponse represents the response of the beacon API
|
| 26 |
-
type BeaconAPIResponse struct {
|
| 27 |
-
Result json.RawMessage
|
| 28 |
-
}
|
| 29 |
-
|
| 30 |
-
// JSONRPCBeaconCall executes restapi call to beacon-api node
|
| 31 |
-
func JSONRPCBeaconCall(ctx context.Context, urlBase, methodPath string) (BeaconAPIResponse, error) {
|
| 32 |
-
//url := path.Join(urlBase, methodPath)
|
| 33 |
-
url := fmt.Sprintf("%s%s", urlBase, methodPath)
|
| 34 |
-
httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody)
|
| 35 |
-
if err != nil {
|
| 36 |
-
return BeaconAPIResponse{}, err
|
| 37 |
-
}
|
| 38 |
-
httpReq.Header.Add("Content-type", "application/json")
|
| 39 |
-
|
| 40 |
-
httpRes, err := http.DefaultClient.Do(httpReq)
|
| 41 |
-
if err != nil {
|
| 42 |
-
return BeaconAPIResponse{}, err
|
| 43 |
-
}
|
| 44 |
-
|
| 45 |
-
resBody, err := io.ReadAll(httpRes.Body)
|
| 46 |
-
if err != nil {
|
| 47 |
-
return BeaconAPIResponse{}, err
|
| 48 |
-
}
|
| 49 |
-
defer httpRes.Body.Close()
|
| 50 |
-
|
| 51 |
-
if httpRes.StatusCode != http.StatusOK {
|
| 52 |
-
return BeaconAPIResponse{}, fmt.Errorf("BeaconClient fails url:%s status_code:%v response:%v", url, httpRes.StatusCode, string(resBody))
|
| 53 |
-
}
|
| 54 |
-
|
| 55 |
-
return BeaconAPIResponse{
|
| 56 |
-
Result: resBody,
|
| 57 |
-
}, nil
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
func unserializeGenericResponse[T any](response BeaconAPIResponse) (T, error) {
|
| 61 |
-
var result T
|
| 62 |
-
err := json.Unmarshal(response.Result, &result)
|
| 63 |
-
if err != nil {
|
| 64 |
-
var zero T
|
| 65 |
-
return zero, err
|
| 66 |
-
}
|
| 67 |
-
return result, nil
|
| 68 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,92 +0,0 @@
|
|
| 1 |
-
package beaconclient
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
"strconv"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 9 |
-
)
|
| 10 |
-
|
| 11 |
-
const beaconBlobSidecarsPath = "/eth/v1/beacon/blob_sidecars/"
|
| 12 |
-
|
| 13 |
-
// BeaconBlobSidecarsResponse represents the response of the beacon blob sidecars endpoint
|
| 14 |
-
type BeaconBlobSidecarsResponse struct {
|
| 15 |
-
Sidecars map[uint64]BeaconBlobSidecarResponse
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
// BeaconBlobSidecarResponse represents the response of the config spec endpoint
|
| 19 |
-
type BeaconBlobSidecarResponse struct {
|
| 20 |
-
Index uint64
|
| 21 |
-
KzgCommitment string
|
| 22 |
-
Blob []byte
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
type beaconBlobSidecarsResponseInternal struct {
|
| 26 |
-
Data []struct {
|
| 27 |
-
Index string `json:"index"`
|
| 28 |
-
Blob string `json:"blob"`
|
| 29 |
-
KzgCommitment string `json:"kzg_commitment"`
|
| 30 |
-
KzgProof string `json:"kzg_proof"`
|
| 31 |
-
SignedBlockHeader struct {
|
| 32 |
-
Message struct {
|
| 33 |
-
Slot string `json:"slot"`
|
| 34 |
-
ProposerIndex string `json:"proposer_index"`
|
| 35 |
-
ParentRoot string `json:"parent_root"`
|
| 36 |
-
StateRoot string `json:"state_root"`
|
| 37 |
-
BodyRoot string `json:"body_root"`
|
| 38 |
-
} `json:"message"`
|
| 39 |
-
Signature string `json:"signature"`
|
| 40 |
-
} `json:"signed_block_header"`
|
| 41 |
-
KzgCommitmentInclusionProof []string `json:"kzg_commitment_inclusion_proof"`
|
| 42 |
-
} `json:"data"`
|
| 43 |
-
}
|
| 44 |
-
|
| 45 |
-
func has0xPrefix(str string) bool {
|
| 46 |
-
return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
func convertBeaconBlobSidecarsResponseInternal(data beaconBlobSidecarsResponseInternal) (*BeaconBlobSidecarsResponse, error) {
|
| 50 |
-
response := BeaconBlobSidecarsResponse{
|
| 51 |
-
Sidecars: make(map[uint64]BeaconBlobSidecarResponse),
|
| 52 |
-
}
|
| 53 |
-
for _, sidecar := range data.Data {
|
| 54 |
-
index, err := strconv.ParseUint(sidecar.Index, 0, hex.BitSize64)
|
| 55 |
-
if err != nil {
|
| 56 |
-
return nil, fmt.Errorf("error parsing Index: %v", err)
|
| 57 |
-
}
|
| 58 |
-
//common.Hex2Bytes(sidecar.Blob)
|
| 59 |
-
if has0xPrefix(sidecar.Blob) {
|
| 60 |
-
sidecar.Blob = sidecar.Blob[2:]
|
| 61 |
-
}
|
| 62 |
-
blob, err := hex.DecodeHex(sidecar.Blob)
|
| 63 |
-
if err != nil {
|
| 64 |
-
return nil, fmt.Errorf("error decoding Blob: %v", err)
|
| 65 |
-
}
|
| 66 |
-
response.Sidecars[index] = BeaconBlobSidecarResponse{
|
| 67 |
-
Index: index,
|
| 68 |
-
KzgCommitment: sidecar.KzgCommitment,
|
| 69 |
-
Blob: blob,
|
| 70 |
-
}
|
| 71 |
-
}
|
| 72 |
-
return &response, nil
|
| 73 |
-
}
|
| 74 |
-
|
| 75 |
-
// BeaconBlobSidecars fetches the blob sidecars for a given blockID
|
| 76 |
-
func (c *BeaconAPIClient) BeaconBlobSidecars(ctx context.Context, blockID uint64) (*BeaconBlobSidecarsResponse, error) {
|
| 77 |
-
response, err := JSONRPCBeaconCall(ctx, c.urlBase, beaconBlobSidecarsPath+fmt.Sprintf("%d", blockID))
|
| 78 |
-
if err != nil {
|
| 79 |
-
return nil, err
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
internalStruct, err := unserializeGenericResponse[beaconBlobSidecarsResponseInternal](response)
|
| 83 |
-
if err != nil {
|
| 84 |
-
return nil, err
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
responseData, err := convertBeaconBlobSidecarsResponseInternal(internalStruct)
|
| 88 |
-
if err != nil {
|
| 89 |
-
return nil, err
|
| 90 |
-
}
|
| 91 |
-
return responseData, nil
|
| 92 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,60 +0,0 @@
|
|
| 1 |
-
package beaconclient
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
"strconv"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 9 |
-
"github.com/ethereum/go-ethereum/common"
|
| 10 |
-
)
|
| 11 |
-
|
| 12 |
-
// /eth/v1/beacon/genesis
|
| 13 |
-
const beaconGenesisPath = "/eth/v1/beacon/genesis"
|
| 14 |
-
|
| 15 |
-
// BeaconGenesisResponse represents the response of the beacon genesis endpoint
|
| 16 |
-
type BeaconGenesisResponse struct {
|
| 17 |
-
GenesisTime uint64
|
| 18 |
-
GenesisValidatorsRoot common.Address
|
| 19 |
-
GenesisForkVersion string
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
type beaconGenesisResponseInternal struct {
|
| 23 |
-
Data struct {
|
| 24 |
-
GenesisTime string `json:"genesis_time"`
|
| 25 |
-
GenesisValidatorsRoot string `json:"genesis_validators_root"`
|
| 26 |
-
GenesisForkVersion string `json:"genesis_fork_version"`
|
| 27 |
-
} `json:"data"`
|
| 28 |
-
}
|
| 29 |
-
|
| 30 |
-
func convertBeaconGenesisResponseInternal(data beaconGenesisResponseInternal) (BeaconGenesisResponse, error) {
|
| 31 |
-
genesisTime, err := strconv.ParseUint(data.Data.GenesisTime, 0, hex.BitSize64)
|
| 32 |
-
if err != nil {
|
| 33 |
-
return BeaconGenesisResponse{}, fmt.Errorf("error parsing genesisTime: %v", err)
|
| 34 |
-
}
|
| 35 |
-
res := BeaconGenesisResponse{
|
| 36 |
-
GenesisTime: genesisTime,
|
| 37 |
-
GenesisValidatorsRoot: common.HexToAddress(data.Data.GenesisValidatorsRoot),
|
| 38 |
-
GenesisForkVersion: data.Data.GenesisForkVersion,
|
| 39 |
-
}
|
| 40 |
-
return res, nil
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
// BeaconGenesis request the current beacon chain genesis
|
| 44 |
-
func (c *BeaconAPIClient) BeaconGenesis(ctx context.Context) (*BeaconGenesisResponse, error) {
|
| 45 |
-
response, err := JSONRPCBeaconCall(ctx, c.urlBase, beaconGenesisPath)
|
| 46 |
-
if err != nil {
|
| 47 |
-
return nil, err
|
| 48 |
-
}
|
| 49 |
-
|
| 50 |
-
internalStruct, err := unserializeGenericResponse[beaconGenesisResponseInternal](response)
|
| 51 |
-
if err != nil {
|
| 52 |
-
return nil, err
|
| 53 |
-
}
|
| 54 |
-
|
| 55 |
-
responseData, err := convertBeaconGenesisResponseInternal(internalStruct)
|
| 56 |
-
if err != nil {
|
| 57 |
-
return nil, err
|
| 58 |
-
}
|
| 59 |
-
return &responseData, nil
|
| 60 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,64 +0,0 @@
|
|
| 1 |
-
package beaconclient
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
"strconv"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 9 |
-
)
|
| 10 |
-
|
| 11 |
-
// ConfigSpec returns the current beacon chain configuration
|
| 12 |
-
// Curl example:
|
| 13 |
-
// curl -X 'GET' \
|
| 14 |
-
// 'http://localhost/eth/v1/config/spec' \
|
| 15 |
-
// -H 'accept: application/json'
|
| 16 |
-
const configSpecPath = "/eth/v1/config/spec"
|
| 17 |
-
|
| 18 |
-
// ConfigSpecNodeResponse represents the response of the config spec endpoint
|
| 19 |
-
type ConfigSpecNodeResponse struct {
|
| 20 |
-
SecondsPerSlot uint64
|
| 21 |
-
SecondsPerEth1Block uint64
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
type configSpecNodeResponseInternal struct {
|
| 25 |
-
Data struct {
|
| 26 |
-
SecondsPerSlot string `json:"SECONDS_PER_SLOT"`
|
| 27 |
-
SecondsPerEth1Block string `json:"SECONDS_PER_ETH1_BLOCK"`
|
| 28 |
-
}
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
-
func convertConfigSpecResponseInternal(data configSpecNodeResponseInternal) (ConfigSpecNodeResponse, error) {
|
| 32 |
-
tmpSecondsPerSlot, err := strconv.ParseUint(data.Data.SecondsPerSlot, 0, hex.BitSize64)
|
| 33 |
-
if err != nil {
|
| 34 |
-
return ConfigSpecNodeResponse{}, fmt.Errorf("error parsing SecondsPerSlot: %v", err)
|
| 35 |
-
}
|
| 36 |
-
tmpSecondsPerEth1Block, err := strconv.ParseUint(data.Data.SecondsPerEth1Block, 0, hex.BitSize64)
|
| 37 |
-
if err != nil {
|
| 38 |
-
return ConfigSpecNodeResponse{}, fmt.Errorf("error parsing SecondsPerSlot: %v", err)
|
| 39 |
-
}
|
| 40 |
-
res := ConfigSpecNodeResponse{
|
| 41 |
-
SecondsPerSlot: tmpSecondsPerSlot,
|
| 42 |
-
SecondsPerEth1Block: tmpSecondsPerEth1Block,
|
| 43 |
-
}
|
| 44 |
-
return res, nil
|
| 45 |
-
}
|
| 46 |
-
|
| 47 |
-
// ConfigSpec returns the current beacon chain configuration
|
| 48 |
-
func (c *BeaconAPIClient) ConfigSpec(ctx context.Context) (*ConfigSpecNodeResponse, error) {
|
| 49 |
-
response, err := JSONRPCBeaconCall(ctx, c.urlBase, configSpecPath)
|
| 50 |
-
if err != nil {
|
| 51 |
-
return nil, err
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
internalStruct, err := unserializeGenericResponse[configSpecNodeResponseInternal](response)
|
| 55 |
-
if err != nil {
|
| 56 |
-
return nil, err
|
| 57 |
-
}
|
| 58 |
-
|
| 59 |
-
responseData, err := convertConfigSpecResponseInternal(internalStruct)
|
| 60 |
-
if err != nil {
|
| 61 |
-
return nil, err
|
| 62 |
-
}
|
| 63 |
-
return &responseData, nil
|
| 64 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -51,14 +51,14 @@
|
|
| 51 |
setupLog(c.Log)
|
| 52 |
|
| 53 |
// Check if it is already registered
|
| 54 |
-
etherman, err := newEtherman(*c)
|
| 55 |
if err != nil {
|
| 56 |
log.Fatal(err)
|
| 57 |
return err
|
| 58 |
}
|
| 59 |
|
| 60 |
// load auth from keystore file
|
| 61 |
-
auth, err := etherman.LoadAuthFromKeyStore(addrKeyStorePath, addrPassword)
|
| 62 |
if err != nil {
|
| 63 |
log.Fatal(err)
|
| 64 |
return err
|
|
|
|
| 51 |
setupLog(c.Log)
|
| 52 |
|
| 53 |
// Check if it is already registered
|
| 54 |
+
etherman, err := newEtherman(*c, nil)
|
| 55 |
if err != nil {
|
| 56 |
log.Fatal(err)
|
| 57 |
return err
|
| 58 |
}
|
| 59 |
|
| 60 |
// load auth from keystore file
|
| 61 |
+
auth, _, err := etherman.LoadAuthFromKeyStore(addrKeyStorePath, addrPassword)
|
| 62 |
if err != nil {
|
| 63 |
log.Fatal(err)
|
| 64 |
return err
|
|
@@ -47,7 +47,7 @@
|
|
| 47 |
networkFlag = cli.StringFlag{
|
| 48 |
Name: config.FlagNetwork,
|
| 49 |
Aliases: []string{"net"},
|
| 50 |
-
Usage: "Load default network configuration. Supported values: [`
|
| 51 |
Required: true,
|
| 52 |
}
|
| 53 |
customNetworkFlag = cli.StringFlag{
|
|
@@ -186,6 +186,13 @@
|
|
| 186 |
Action: restore,
|
| 187 |
Flags: restoreFlags,
|
| 188 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
}
|
| 190 |
|
| 191 |
err := app.Run(os.Args)
|
|
|
|
| 47 |
networkFlag = cli.StringFlag{
|
| 48 |
Name: config.FlagNetwork,
|
| 49 |
Aliases: []string{"net"},
|
| 50 |
+
Usage: "Load default network configuration. Supported values: [`custom`]",
|
| 51 |
Required: true,
|
| 52 |
}
|
| 53 |
customNetworkFlag = cli.StringFlag{
|
|
|
|
| 186 |
Action: restore,
|
| 187 |
Flags: restoreFlags,
|
| 188 |
},
|
| 189 |
+
{
|
| 190 |
+
Name: "set-data-availability-protocol",
|
| 191 |
+
Aliases: []string{"set-dap"},
|
| 192 |
+
Usage: "Sets the new data availability protocol",
|
| 193 |
+
Action: setDataAvailabilityProtocol,
|
| 194 |
+
Flags: setDataAvailabilityProtocolFlags,
|
| 195 |
+
},
|
| 196 |
}
|
| 197 |
|
| 198 |
err := app.Run(os.Args)
|
|
@@ -0,0 +1,308 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package main
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"encoding/csv"
|
| 6 |
+
"errors"
|
| 7 |
+
"fmt"
|
| 8 |
+
"os"
|
| 9 |
+
"strings"
|
| 10 |
+
|
| 11 |
+
"github.com/0xPolygonHermez/zkevm-node/config"
|
| 12 |
+
"github.com/0xPolygonHermez/zkevm-node/pool"
|
| 13 |
+
"github.com/0xPolygonHermez/zkevm-node/pool/pgpoolstorage"
|
| 14 |
+
"github.com/ethereum/go-ethereum/common"
|
| 15 |
+
"github.com/urfave/cli/v2"
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
var (
|
| 19 |
+
policyFlag = cli.StringFlag{
|
| 20 |
+
Name: "policy",
|
| 21 |
+
Aliases: []string{"p"},
|
| 22 |
+
Usage: "Name of policy to operate on",
|
| 23 |
+
Required: false,
|
| 24 |
+
}
|
| 25 |
+
csvFlag = cli.StringFlag{
|
| 26 |
+
Name: "csv",
|
| 27 |
+
Usage: "CSV file with addresses",
|
| 28 |
+
Required: false,
|
| 29 |
+
}
|
| 30 |
+
allowFlag = cli.BoolFlag{
|
| 31 |
+
Name: "allow",
|
| 32 |
+
Usage: "Update policy to 'allow' addresses on list",
|
| 33 |
+
Required: false,
|
| 34 |
+
}
|
| 35 |
+
denyFlag = cli.BoolFlag{
|
| 36 |
+
Name: "deny",
|
| 37 |
+
Usage: "Update policy to 'deny' addresses on list",
|
| 38 |
+
Required: false,
|
| 39 |
+
}
|
| 40 |
+
noHeaderFlag = cli.BoolFlag{
|
| 41 |
+
Name: "no-header",
|
| 42 |
+
Value: false,
|
| 43 |
+
Required: false,
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
policyActionFlags = []cli.Flag{&policyFlag}
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
var policyCommands = cli.Command{
|
| 50 |
+
Name: "policy",
|
| 51 |
+
Usage: "View, update, and apply policies",
|
| 52 |
+
Action: describe,
|
| 53 |
+
Flags: []cli.Flag{&configFileFlag},
|
| 54 |
+
Subcommands: []*cli.Command{
|
| 55 |
+
{
|
| 56 |
+
Name: "add",
|
| 57 |
+
Usage: "Add address(es) to a policy exclusion list",
|
| 58 |
+
Action: addAcl,
|
| 59 |
+
Flags: append(policyActionFlags, &csvFlag),
|
| 60 |
+
}, {
|
| 61 |
+
Name: "clear",
|
| 62 |
+
Usage: "Clear the addresses listed as exceptions to a policy",
|
| 63 |
+
Action: clearAcl,
|
| 64 |
+
Flags: policyActionFlags,
|
| 65 |
+
}, {
|
| 66 |
+
Name: "describe",
|
| 67 |
+
Usage: "Describe the default actions for the policies",
|
| 68 |
+
Action: describe,
|
| 69 |
+
Flags: append(policyActionFlags, &noHeaderFlag),
|
| 70 |
+
}, {
|
| 71 |
+
Name: "remove",
|
| 72 |
+
Usage: "Remove address(es) from a policy exclusion list",
|
| 73 |
+
Action: removeAcl,
|
| 74 |
+
Flags: append(policyActionFlags, &csvFlag),
|
| 75 |
+
}, {
|
| 76 |
+
Name: "update",
|
| 77 |
+
Usage: "Update the default action for a policy",
|
| 78 |
+
Action: updatePolicy,
|
| 79 |
+
Flags: append(policyActionFlags, &allowFlag, &denyFlag),
|
| 80 |
+
},
|
| 81 |
+
},
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
func updatePolicy(cli *cli.Context) error {
|
| 85 |
+
_, db, err := configAndStorage(cli)
|
| 86 |
+
if err != nil {
|
| 87 |
+
return err
|
| 88 |
+
}
|
| 89 |
+
policy, err := resolvePolicy(cli)
|
| 90 |
+
if err != nil {
|
| 91 |
+
return err
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
allow := cli.Bool(allowFlag.Name)
|
| 95 |
+
deny := cli.Bool(denyFlag.Name)
|
| 96 |
+
|
| 97 |
+
// exactly one must be set
|
| 98 |
+
if (allow && deny) || (!allow && !deny) {
|
| 99 |
+
return errors.New("supply one policy action [--allow or --deny]")
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
var setting bool
|
| 103 |
+
if allow {
|
| 104 |
+
setting = true
|
| 105 |
+
} else if deny {
|
| 106 |
+
setting = false
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
err = db.UpdatePolicy(context.Background(), policy, setting)
|
| 110 |
+
if err != nil {
|
| 111 |
+
return err
|
| 112 |
+
}
|
| 113 |
+
return nil
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
func addAcl(cli *cli.Context) error {
|
| 117 |
+
_, db, err := configAndStorage(cli)
|
| 118 |
+
if err != nil {
|
| 119 |
+
return err
|
| 120 |
+
}
|
| 121 |
+
policy, addresses, err := requirePolicyAndAddresses(cli)
|
| 122 |
+
if err != nil {
|
| 123 |
+
return err
|
| 124 |
+
}
|
| 125 |
+
err = db.AddAddressesToPolicy(context.Background(), policy, addresses)
|
| 126 |
+
if err != nil {
|
| 127 |
+
return err
|
| 128 |
+
}
|
| 129 |
+
return nil
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
func removeAcl(cli *cli.Context) error {
|
| 133 |
+
_, db, err := configAndStorage(cli)
|
| 134 |
+
if err != nil {
|
| 135 |
+
return err
|
| 136 |
+
}
|
| 137 |
+
policy, addresses, err := requirePolicyAndAddresses(cli)
|
| 138 |
+
if err != nil {
|
| 139 |
+
return err
|
| 140 |
+
}
|
| 141 |
+
err = db.RemoveAddressesFromPolicy(context.Background(), policy, addresses)
|
| 142 |
+
if err != nil {
|
| 143 |
+
return err
|
| 144 |
+
}
|
| 145 |
+
return nil
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
func clearAcl(cli *cli.Context) error {
|
| 149 |
+
_, db, err := configAndStorage(cli)
|
| 150 |
+
if err != nil {
|
| 151 |
+
return err
|
| 152 |
+
}
|
| 153 |
+
policy, err := resolvePolicy(cli)
|
| 154 |
+
if err != nil {
|
| 155 |
+
return err
|
| 156 |
+
}
|
| 157 |
+
err = db.ClearPolicy(context.Background(), policy)
|
| 158 |
+
if err != nil {
|
| 159 |
+
return err
|
| 160 |
+
}
|
| 161 |
+
return nil
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
func describe(cli *cli.Context) error {
|
| 165 |
+
showHeader := !cli.Bool(noHeaderFlag.Name)
|
| 166 |
+
if cli.IsSet(policyFlag.Name) {
|
| 167 |
+
return describePolicy(cli, showHeader)
|
| 168 |
+
}
|
| 169 |
+
return describePolicies(cli, showHeader)
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
func describePolicy(cli *cli.Context, showHeader bool) error {
|
| 173 |
+
_, db, err := configAndStorage(cli)
|
| 174 |
+
if err != nil {
|
| 175 |
+
return err
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
policyName, err := resolvePolicy(cli)
|
| 179 |
+
if err != nil {
|
| 180 |
+
return err
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
if showHeader {
|
| 184 |
+
policy, err := db.DescribePolicy(context.Background(), policyName)
|
| 185 |
+
if err != nil {
|
| 186 |
+
return err
|
| 187 |
+
}
|
| 188 |
+
fmt.Printf("%s: %s\n", "Policy", policy.Name)
|
| 189 |
+
fmt.Printf("%s: %s\n", "Action", policy.Desc())
|
| 190 |
+
}
|
| 191 |
+
query, err := resolveAddresses(cli, false)
|
| 192 |
+
if err != nil {
|
| 193 |
+
return nil
|
| 194 |
+
}
|
| 195 |
+
list, err := db.ListAcl(context.Background(), policyName, query)
|
| 196 |
+
if err != nil {
|
| 197 |
+
return err
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
if showHeader {
|
| 201 |
+
fmt.Println("Addresses:")
|
| 202 |
+
}
|
| 203 |
+
for _, address := range list {
|
| 204 |
+
fmt.Println(address.Hex())
|
| 205 |
+
}
|
| 206 |
+
return nil
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
func describePolicies(cli *cli.Context, showHeader bool) error {
|
| 210 |
+
_, db, err := configAndStorage(cli)
|
| 211 |
+
if err != nil {
|
| 212 |
+
return err
|
| 213 |
+
}
|
| 214 |
+
list, err := db.DescribePolicies(context.Background())
|
| 215 |
+
if err != nil {
|
| 216 |
+
return err
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
if showHeader {
|
| 220 |
+
fmt.Printf("%7s: %s\n", "Policy", "Action")
|
| 221 |
+
}
|
| 222 |
+
for _, p := range list {
|
| 223 |
+
fmt.Printf("%7s: %s\n", p.Name, p.Desc())
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
return nil
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
func configAndStorage(cli *cli.Context) (*config.Config, *pgpoolstorage.PostgresPoolStorage, error) {
|
| 230 |
+
c, err := config.Load(cli, false)
|
| 231 |
+
if err != nil {
|
| 232 |
+
return nil, nil, err
|
| 233 |
+
}
|
| 234 |
+
setupLog(c.Log)
|
| 235 |
+
|
| 236 |
+
db, err := pgpoolstorage.NewPostgresPoolStorage(c.Pool.DB)
|
| 237 |
+
if err != nil {
|
| 238 |
+
return nil, nil, err
|
| 239 |
+
}
|
| 240 |
+
return c, db, nil
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
func requirePolicyAndAddresses(cli *cli.Context) (pool.PolicyName, []common.Address, error) {
|
| 244 |
+
policy, err := resolvePolicy(cli)
|
| 245 |
+
if err != nil {
|
| 246 |
+
return "", nil, err
|
| 247 |
+
}
|
| 248 |
+
addresses, err := resolveAddresses(cli, true)
|
| 249 |
+
if err != nil {
|
| 250 |
+
return "", nil, err
|
| 251 |
+
}
|
| 252 |
+
return policy, addresses, nil
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
func resolvePolicy(cli *cli.Context) (pool.PolicyName, error) {
|
| 256 |
+
policy := cli.String(policyFlag.Name)
|
| 257 |
+
if policy == "" {
|
| 258 |
+
return "", nil
|
| 259 |
+
}
|
| 260 |
+
if !pool.IsPolicy(policy) {
|
| 261 |
+
return "", fmt.Errorf("invalid policy name: %s", policy)
|
| 262 |
+
}
|
| 263 |
+
return pool.PolicyName(policy), nil
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
func resolveAddresses(cli *cli.Context, failIfEmpty bool) ([]common.Address, error) {
|
| 267 |
+
var set = make(map[common.Address]struct{})
|
| 268 |
+
if cli.IsSet("csv") {
|
| 269 |
+
file := cli.String(csvFlag.Name)
|
| 270 |
+
fd, err := os.Open(file)
|
| 271 |
+
if err != nil {
|
| 272 |
+
return nil, err
|
| 273 |
+
}
|
| 274 |
+
defer func(fd *os.File) {
|
| 275 |
+
_ = fd.Close()
|
| 276 |
+
}(fd)
|
| 277 |
+
|
| 278 |
+
fileReader := csv.NewReader(fd)
|
| 279 |
+
records, err := fileReader.ReadAll()
|
| 280 |
+
|
| 281 |
+
if err != nil {
|
| 282 |
+
return nil, err
|
| 283 |
+
}
|
| 284 |
+
for _, row := range records {
|
| 285 |
+
for _, cell := range row {
|
| 286 |
+
hex := strings.TrimSpace(cell)
|
| 287 |
+
set[common.HexToAddress(hex)] = struct{}{}
|
| 288 |
+
}
|
| 289 |
+
}
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
for _, a := range cli.Args().Slice() {
|
| 293 |
+
a = strings.TrimSpace(a)
|
| 294 |
+
a = strings.Trim(a, ",|")
|
| 295 |
+
if !strings.HasPrefix(a, "0x") {
|
| 296 |
+
a = "0x" + a
|
| 297 |
+
}
|
| 298 |
+
set[common.HexToAddress(a)] = struct{}{}
|
| 299 |
+
}
|
| 300 |
+
var ret []common.Address
|
| 301 |
+
for a := range set {
|
| 302 |
+
ret = append(ret, a)
|
| 303 |
+
}
|
| 304 |
+
if failIfEmpty && len(ret) == 0 {
|
| 305 |
+
return nil, errors.New("no addresses given")
|
| 306 |
+
}
|
| 307 |
+
return ret, nil
|
| 308 |
+
}
|
|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
|
|
|
| 5 |
"errors"
|
| 6 |
"fmt"
|
| 7 |
"net"
|
|
@@ -108,19 +113,27 @@
|
|
| 108 |
log.Fatal(err)
|
| 109 |
}
|
| 110 |
|
| 111 |
-
|
|
|
|
| 112 |
if err != nil {
|
| 113 |
log.Fatal(err)
|
| 114 |
}
|
| 115 |
-
|
| 116 |
-
// READ CHAIN ID FROM POE SC
|
| 117 |
-
l2ChainID, err := etherman.GetL2ChainID()
|
| 118 |
if err != nil {
|
| 119 |
log.Fatal(err)
|
| 120 |
}
|
| 121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
st, currentForkID := newState(cliCtx.Context, c, etherman, l2ChainID, stateSqlDB, eventLog, needsExecutor, needsStateTree, false)
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
c.Aggregator.ChainID = l2ChainID
|
| 125 |
c.Sequencer.StreamServer.ChainID = l2ChainID
|
| 126 |
log.Infof("Chain ID read from POE SC = %v", l2ChainID)
|
|
@@ -277,8 +290,79 @@
|
|
| 277 |
}
|
| 278 |
}
|
| 279 |
|
| 280 |
-
func newEtherman(c config.Config) (*etherman.Client, error) {
|
| 281 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
}
|
| 283 |
|
| 284 |
func newL2EthClient(url string) (*ethclient.Client, error) {
|
|
@@ -321,7 +405,7 @@
|
|
| 321 |
// If synchronizer are using sequential mode, we only need one etherman client
|
| 322 |
if cfg.Synchronizer.L1SynchronizationMode == synchronizer.ParallelMode {
|
| 323 |
for i := 0; i < int(cfg.Synchronizer.L1ParallelSynchronization.MaxClients+1); i++ {
|
| 324 |
-
eth, err := newEtherman(cfg)
|
| 325 |
if err != nil {
|
| 326 |
log.Fatal(err)
|
| 327 |
}
|
|
@@ -424,12 +508,12 @@
|
|
| 424 |
}
|
| 425 |
|
| 426 |
func createSequenceSender(cfg config.Config, pool *pool.Pool, etmStorage *ethtxmanager.PostgresStorage, st *state.State, eventLog *event.EventLog) *sequencesender.SequenceSender {
|
| 427 |
-
etherman, err := newEtherman(cfg)
|
| 428 |
if err != nil {
|
| 429 |
log.Fatal(err)
|
| 430 |
}
|
| 431 |
|
| 432 |
-
auth, err := etherman.LoadAuthFromKeyStore(cfg.SequenceSender.PrivateKey.Path, cfg.SequenceSender.PrivateKey.Password)
|
| 433 |
if err != nil {
|
| 434 |
log.Fatal(err)
|
| 435 |
}
|
|
@@ -439,7 +523,12 @@
|
|
| 439 |
|
| 440 |
ethTxManager := ethtxmanager.New(cfg.EthTxManager, etherman, etmStorage, st)
|
| 441 |
|
| 442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 443 |
if err != nil {
|
| 444 |
log.Fatal(err)
|
| 445 |
}
|
|
@@ -448,7 +537,23 @@
|
|
| 448 |
}
|
| 449 |
|
| 450 |
func runAggregator(ctx context.Context, c aggregator.Config, etherman *etherman.Client, ethTxManager *ethtxmanager.Client, st *state.State) {
|
| 451 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
if err != nil {
|
| 453 |
log.Fatal(err)
|
| 454 |
}
|
|
@@ -510,29 +615,22 @@
|
|
| 510 |
AvoidForkIDInMemory: avoidForkIDInMemory,
|
| 511 |
}
|
| 512 |
stateDb := pgstatestorage.NewPostgresStorage(stateCfg, sqlDB)
|
| 513 |
-
|
| 514 |
-
st := state.NewState(stateCfg, stateDb, executorClient, stateTree, eventLog, nil, nil)
|
| 515 |
// This is to force to build cache, and check that DB is ok before starting the application
|
| 516 |
-
|
| 517 |
if err != nil {
|
| 518 |
log.Fatal("error getting current L1InfoRoot. Error: ", err)
|
| 519 |
}
|
| 520 |
-
log.Infof("Starting L1InfoRoot: %v",
|
| 521 |
|
| 522 |
-
|
| 523 |
-
if err != nil {
|
| 524 |
-
log.Fatal("error getting current l1InfoTreeRecursiveRoot. Error: ", err)
|
| 525 |
-
}
|
| 526 |
-
log.Infof("Starting l1InfoTreeRecursiveRoot: %v", l1InfoTreeRecursiveRoot.String())
|
| 527 |
-
|
| 528 |
-
forkIDIntervals, err := forkIDIntervals(ctx, st, etherman, c.NetworkConfig.Genesis.BlockNumber)
|
| 529 |
if err != nil {
|
| 530 |
log.Fatal("error getting forkIDs. Error: ", err)
|
| 531 |
}
|
| 532 |
st.UpdateForkIDIntervalsInMemory(forkIDIntervals)
|
| 533 |
|
| 534 |
currentForkID := forkIDIntervals[len(forkIDIntervals)-1].ForkId
|
| 535 |
-
log.Infof("Fork ID read from POE SC = %v",
|
| 536 |
|
| 537 |
return st, currentForkID
|
| 538 |
}
|
|
@@ -548,13 +646,13 @@
|
|
| 548 |
}
|
| 549 |
|
| 550 |
func createEthTxManager(cfg config.Config, etmStorage *ethtxmanager.PostgresStorage, st *state.State) *ethtxmanager.Client {
|
| 551 |
-
etherman, err := newEtherman(cfg)
|
| 552 |
if err != nil {
|
| 553 |
log.Fatal(err)
|
| 554 |
}
|
| 555 |
|
| 556 |
for _, privateKey := range cfg.EthTxManager.PrivateKeys {
|
| 557 |
-
_, err := etherman.LoadAuthFromKeyStore(privateKey.Path, privateKey.Password)
|
| 558 |
if err != nil {
|
| 559 |
log.Fatal(err)
|
| 560 |
}
|
|
@@ -646,8 +744,7 @@
|
|
| 646 |
if err != nil && !errors.Is(err, state.ErrStateNotSynchronized) {
|
| 647 |
return []state.ForkIDInterval{}, fmt.Errorf("error checking lastL1BlockSynced. Error: %v", err)
|
| 648 |
}
|
| 649 |
-
|
| 650 |
-
if lastBlock != nil && lastBlock.BlockNumber > genesisBlockNumber {
|
| 651 |
log.Info("Getting forkIDs intervals. Please wait...")
|
| 652 |
// Read Fork ID FROM POE SC
|
| 653 |
forkIntervals, err := etherman.GetForks(ctx, genesisBlockNumber, lastBlock.BlockNumber)
|
|
@@ -687,14 +784,32 @@
|
|
| 687 |
}
|
| 688 |
forkIDIntervals = forkIntervals
|
| 689 |
} else {
|
| 690 |
-
log.Debug("Getting
|
| 691 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 692 |
if err != nil {
|
| 693 |
return []state.ForkIDInterval{}, fmt.Errorf("error getting forks. Please check the configuration. Error: %v", err)
|
| 694 |
} else if len(forkIntervals) == 0 {
|
| 695 |
return []state.ForkIDInterval{}, fmt.Errorf("error: no forkID received. It should receive at least one, please check the configuration...")
|
| 696 |
}
|
| 697 |
forkIDIntervals = forkIntervals
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 698 |
}
|
| 699 |
}
|
| 700 |
return forkIDIntervals, nil
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
| 8 |
"net"
|
|
|
|
| 113 |
log.Fatal(err)
|
| 114 |
}
|
| 115 |
|
| 116 |
+
// READ CHAIN ID FROM POE SC
|
| 117 |
+
tmpEthMan, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 118 |
if err != nil {
|
| 119 |
log.Fatal(err)
|
| 120 |
}
|
| 121 |
+
l2ChainID, err := tmpEthMan.GetL2ChainID()
|
|
|
|
|
|
|
| 122 |
if err != nil {
|
| 123 |
log.Fatal(err)
|
| 124 |
}
|
| 125 |
|
| 126 |
+
etherman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 127 |
+
if err != nil {
|
| 128 |
+
log.Fatal(err)
|
| 129 |
+
}
|
| 130 |
st, currentForkID := newState(cliCtx.Context, c, etherman, l2ChainID, stateSqlDB, eventLog, needsExecutor, needsStateTree, false)
|
| 131 |
|
| 132 |
+
etherman, err = newEtherman(*c, st)
|
| 133 |
+
if err != nil {
|
| 134 |
+
log.Fatal(err)
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
c.Aggregator.ChainID = l2ChainID
|
| 138 |
c.Sequencer.StreamServer.ChainID = l2ChainID
|
| 139 |
log.Infof("Chain ID read from POE SC = %v", l2ChainID)
|
|
|
|
| 290 |
}
|
| 291 |
}
|
| 292 |
|
| 293 |
+
func newEtherman(c config.Config, st *state.State) (*etherman.Client, error) {
|
| 294 |
+
ethman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 295 |
+
if err != nil {
|
| 296 |
+
return nil, err
|
| 297 |
+
}
|
| 298 |
+
da, err := newDataAvailability(c, st, ethman, false)
|
| 299 |
+
if err != nil {
|
| 300 |
+
return nil, err
|
| 301 |
+
}
|
| 302 |
+
return etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, da, st)
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
func newDataAvailability(c config.Config, st *state.State, etherman *etherman.Client, isSequenceSender bool) (*dataavailability.DataAvailability, error) {
|
| 306 |
+
var (
|
| 307 |
+
trustedSequencerURL string
|
| 308 |
+
err error
|
| 309 |
+
)
|
| 310 |
+
if !c.IsTrustedSequencer {
|
| 311 |
+
if c.Synchronizer.TrustedSequencerURL != "" {
|
| 312 |
+
trustedSequencerURL = c.Synchronizer.TrustedSequencerURL
|
| 313 |
+
} else {
|
| 314 |
+
log.Debug("getting trusted sequencer URL from smc")
|
| 315 |
+
trustedSequencerURL, err = etherman.GetTrustedSequencerURL()
|
| 316 |
+
if err != nil {
|
| 317 |
+
return nil, fmt.Errorf("error getting trusted sequencer URI. Error: %v", err)
|
| 318 |
+
}
|
| 319 |
+
}
|
| 320 |
+
log.Debug("trustedSequencerURL ", trustedSequencerURL)
|
| 321 |
+
}
|
| 322 |
+
zkEVMClient := client.NewClient(trustedSequencerURL)
|
| 323 |
+
|
| 324 |
+
// Backend specific config
|
| 325 |
+
daProtocolName, err := etherman.GetDAProtocolName()
|
| 326 |
+
if err != nil {
|
| 327 |
+
return nil, fmt.Errorf("error getting data availability protocol name: %v", err)
|
| 328 |
+
}
|
| 329 |
+
var daBackend dataavailability.DABackender
|
| 330 |
+
switch daProtocolName {
|
| 331 |
+
case string(dataavailability.DataAvailabilityCommittee):
|
| 332 |
+
var (
|
| 333 |
+
pk *ecdsa.PrivateKey
|
| 334 |
+
err error
|
| 335 |
+
)
|
| 336 |
+
if isSequenceSender {
|
| 337 |
+
_, pk, err = etherman.LoadAuthFromKeyStore(c.SequenceSender.PrivateKey.Path, c.SequenceSender.PrivateKey.Password)
|
| 338 |
+
if err != nil {
|
| 339 |
+
return nil, err
|
| 340 |
+
}
|
| 341 |
+
}
|
| 342 |
+
dacAddr, err := etherman.GetDAProtocolAddr()
|
| 343 |
+
if err != nil {
|
| 344 |
+
return nil, fmt.Errorf("error getting trusted sequencer URI. Error: %v", err)
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
daBackend, err = datacommittee.New(
|
| 348 |
+
c.Etherman.URL,
|
| 349 |
+
dacAddr,
|
| 350 |
+
pk,
|
| 351 |
+
dataCommitteeClient.NewFactory(),
|
| 352 |
+
)
|
| 353 |
+
if err != nil {
|
| 354 |
+
return nil, err
|
| 355 |
+
}
|
| 356 |
+
default:
|
| 357 |
+
return nil, fmt.Errorf("unexpected / unsupported DA protocol: %s", daProtocolName)
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
return dataavailability.New(
|
| 361 |
+
c.IsTrustedSequencer,
|
| 362 |
+
daBackend,
|
| 363 |
+
st,
|
| 364 |
+
zkEVMClient,
|
| 365 |
+
)
|
| 366 |
}
|
| 367 |
|
| 368 |
func newL2EthClient(url string) (*ethclient.Client, error) {
|
|
|
|
| 405 |
// If synchronizer are using sequential mode, we only need one etherman client
|
| 406 |
if cfg.Synchronizer.L1SynchronizationMode == synchronizer.ParallelMode {
|
| 407 |
for i := 0; i < int(cfg.Synchronizer.L1ParallelSynchronization.MaxClients+1); i++ {
|
| 408 |
+
eth, err := newEtherman(cfg, st)
|
| 409 |
if err != nil {
|
| 410 |
log.Fatal(err)
|
| 411 |
}
|
|
|
|
| 508 |
}
|
| 509 |
|
| 510 |
func createSequenceSender(cfg config.Config, pool *pool.Pool, etmStorage *ethtxmanager.PostgresStorage, st *state.State, eventLog *event.EventLog) *sequencesender.SequenceSender {
|
| 511 |
+
etherman, err := newEtherman(cfg, st)
|
| 512 |
if err != nil {
|
| 513 |
log.Fatal(err)
|
| 514 |
}
|
| 515 |
|
| 516 |
+
auth, _, err := etherman.LoadAuthFromKeyStore(cfg.SequenceSender.PrivateKey.Path, cfg.SequenceSender.PrivateKey.Password)
|
| 517 |
if err != nil {
|
| 518 |
log.Fatal(err)
|
| 519 |
}
|
|
|
|
| 523 |
|
| 524 |
ethTxManager := ethtxmanager.New(cfg.EthTxManager, etherman, etmStorage, st)
|
| 525 |
|
| 526 |
+
da, err := newDataAvailability(cfg, st, etherman, true)
|
| 527 |
+
if err != nil {
|
| 528 |
+
log.Fatal(err)
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
seqSender, err := sequencesender.New(cfg.SequenceSender, st, etherman, ethTxManager, eventLog, da)
|
| 532 |
if err != nil {
|
| 533 |
log.Fatal(err)
|
| 534 |
}
|
|
|
|
| 537 |
}
|
| 538 |
|
| 539 |
func runAggregator(ctx context.Context, c aggregator.Config, etherman *etherman.Client, ethTxManager *ethtxmanager.Client, st *state.State) {
|
| 540 |
+
var (
|
| 541 |
+
aggCli *agglayerClient.Client
|
| 542 |
+
pk *ecdsa.PrivateKey
|
| 543 |
+
err error
|
| 544 |
+
)
|
| 545 |
+
|
| 546 |
+
if c.SettlementBackend == aggregator.AggLayer {
|
| 547 |
+
aggCli = agglayerClient.New(c.AggLayerURL)
|
| 548 |
+
|
| 549 |
+
// Load private key
|
| 550 |
+
pk, err = config.NewKeyFromKeystore(c.SequencerPrivateKey)
|
| 551 |
+
if err != nil {
|
| 552 |
+
log.Fatal(err)
|
| 553 |
+
}
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
agg, err := aggregator.New(c, st, ethTxManager, etherman, aggCli, pk)
|
| 557 |
if err != nil {
|
| 558 |
log.Fatal(err)
|
| 559 |
}
|
|
|
|
| 615 |
AvoidForkIDInMemory: avoidForkIDInMemory,
|
| 616 |
}
|
| 617 |
stateDb := pgstatestorage.NewPostgresStorage(stateCfg, sqlDB)
|
| 618 |
+
st := state.NewState(stateCfg, stateDb, executorClient, stateTree, eventLog, nil)
|
|
|
|
| 619 |
// This is to force to build cache, and check that DB is ok before starting the application
|
| 620 |
+
l1inforoot, err := st.GetCurrentL1InfoRoot(ctx, nil)
|
| 621 |
if err != nil {
|
| 622 |
log.Fatal("error getting current L1InfoRoot. Error: ", err)
|
| 623 |
}
|
| 624 |
+
log.Infof("Starting L1InfoRoot: %v", l1inforoot.String())
|
| 625 |
|
| 626 |
+
forkIDIntervals, err := forkIDIntervals(ctx, st, etherman, c.NetworkConfig.Genesis.RollupBlockNumber)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 627 |
if err != nil {
|
| 628 |
log.Fatal("error getting forkIDs. Error: ", err)
|
| 629 |
}
|
| 630 |
st.UpdateForkIDIntervalsInMemory(forkIDIntervals)
|
| 631 |
|
| 632 |
currentForkID := forkIDIntervals[len(forkIDIntervals)-1].ForkId
|
| 633 |
+
log.Infof("Fork ID read from POE SC = %v", currentForkID)
|
| 634 |
|
| 635 |
return st, currentForkID
|
| 636 |
}
|
|
|
|
| 646 |
}
|
| 647 |
|
| 648 |
func createEthTxManager(cfg config.Config, etmStorage *ethtxmanager.PostgresStorage, st *state.State) *ethtxmanager.Client {
|
| 649 |
+
etherman, err := newEtherman(cfg, st)
|
| 650 |
if err != nil {
|
| 651 |
log.Fatal(err)
|
| 652 |
}
|
| 653 |
|
| 654 |
for _, privateKey := range cfg.EthTxManager.PrivateKeys {
|
| 655 |
+
_, _, err := etherman.LoadAuthFromKeyStore(privateKey.Path, privateKey.Password)
|
| 656 |
if err != nil {
|
| 657 |
log.Fatal(err)
|
| 658 |
}
|
|
|
|
| 744 |
if err != nil && !errors.Is(err, state.ErrStateNotSynchronized) {
|
| 745 |
return []state.ForkIDInterval{}, fmt.Errorf("error checking lastL1BlockSynced. Error: %v", err)
|
| 746 |
}
|
| 747 |
+
if lastBlock != nil {
|
|
|
|
| 748 |
log.Info("Getting forkIDs intervals. Please wait...")
|
| 749 |
// Read Fork ID FROM POE SC
|
| 750 |
forkIntervals, err := etherman.GetForks(ctx, genesisBlockNumber, lastBlock.BlockNumber)
|
|
|
|
| 784 |
}
|
| 785 |
forkIDIntervals = forkIntervals
|
| 786 |
} else {
|
| 787 |
+
log.Debug("Getting all forkIDs")
|
| 788 |
+
|
| 789 |
+
// Get last L1 block number
|
| 790 |
+
bn, err := etherman.GetLatestBlockNumber(ctx)
|
| 791 |
+
if err != nil {
|
| 792 |
+
return []state.ForkIDInterval{}, fmt.Errorf("error getting latest block number. Error: %v", err)
|
| 793 |
+
}
|
| 794 |
+
|
| 795 |
+
// Get all forkIDs since genesis
|
| 796 |
+
forkIntervals, err := etherman.GetForks(ctx, genesisBlockNumber, bn)
|
| 797 |
if err != nil {
|
| 798 |
return []state.ForkIDInterval{}, fmt.Errorf("error getting forks. Please check the configuration. Error: %v", err)
|
| 799 |
} else if len(forkIntervals) == 0 {
|
| 800 |
return []state.ForkIDInterval{}, fmt.Errorf("error: no forkID received. It should receive at least one, please check the configuration...")
|
| 801 |
}
|
| 802 |
forkIDIntervals = forkIntervals
|
| 803 |
+
|
| 804 |
+
log.Debugf("Retrieved %d forkIDs", len(forkIDIntervals))
|
| 805 |
+
|
| 806 |
+
log.Debug("Adding forkIDs to db and memory")
|
| 807 |
+
for _, forkID := range forkIDIntervals {
|
| 808 |
+
err = st.AddForkIDInterval(ctx, forkID, nil)
|
| 809 |
+
if err != nil {
|
| 810 |
+
log.Fatal("error adding forkID to db. Error: ", err)
|
| 811 |
+
}
|
| 812 |
+
}
|
| 813 |
}
|
| 814 |
}
|
| 815 |
return forkIDIntervals, nil
|
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package main
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"github.com/0xPolygonHermez/zkevm-node/config"
|
| 5 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 6 |
+
"github.com/ethereum/go-ethereum/common"
|
| 7 |
+
"github.com/urfave/cli/v2"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
const flagDAAddress = "data-availability-address"
|
| 11 |
+
|
| 12 |
+
var setDataAvailabilityProtocolFlags = []cli.Flag{
|
| 13 |
+
&cli.StringFlag{
|
| 14 |
+
Name: flagDAAddress,
|
| 15 |
+
Aliases: []string{"da-addr"},
|
| 16 |
+
Usage: "address of the new data availibility protocol",
|
| 17 |
+
Required: true,
|
| 18 |
+
},
|
| 19 |
+
&cli.StringFlag{
|
| 20 |
+
Name: config.FlagKeyStorePath,
|
| 21 |
+
Aliases: []string{"ksp"},
|
| 22 |
+
Usage: "the path of the key store file containing the private key of the account going to set new data availability protocol",
|
| 23 |
+
Required: true,
|
| 24 |
+
},
|
| 25 |
+
&cli.StringFlag{
|
| 26 |
+
Name: config.FlagPassword,
|
| 27 |
+
Aliases: []string{"pw"},
|
| 28 |
+
Usage: "the password do decrypt the key store file",
|
| 29 |
+
Required: true,
|
| 30 |
+
},
|
| 31 |
+
&configFileFlag,
|
| 32 |
+
&networkFlag,
|
| 33 |
+
&customNetworkFlag,
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
func setDataAvailabilityProtocol(ctx *cli.Context) error {
|
| 37 |
+
c, err := config.Load(ctx, true)
|
| 38 |
+
if err != nil {
|
| 39 |
+
return err
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
setupLog(c.Log)
|
| 43 |
+
|
| 44 |
+
daAddress := common.HexToAddress(ctx.String(flagDAAddress))
|
| 45 |
+
addrKeyStorePath := ctx.String(config.FlagKeyStorePath)
|
| 46 |
+
addrPassword := ctx.String(config.FlagPassword)
|
| 47 |
+
|
| 48 |
+
etherman, err := newEtherman(*c, nil)
|
| 49 |
+
if err != nil {
|
| 50 |
+
log.Fatal(err)
|
| 51 |
+
return err
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
auth, _, err := etherman.LoadAuthFromKeyStore(addrKeyStorePath, addrPassword)
|
| 55 |
+
if err != nil {
|
| 56 |
+
log.Fatal(err)
|
| 57 |
+
return err
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
tx, err := etherman.SetDataAvailabilityProtocol(auth.From, daAddress)
|
| 61 |
+
if err != nil {
|
| 62 |
+
return err
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
log.Infof("Transaction to set new data availability protocol sent. Hash: %s", tx.Hash())
|
| 66 |
+
|
| 67 |
+
return nil
|
| 68 |
+
}
|
|
@@ -1,109 +0,0 @@
|
|
| 1 |
-
package config
|
| 2 |
-
|
| 3 |
-
// CardonaNetworkConfigJSON is the hardcoded network configuration to be used for the official mainnet setup
|
| 4 |
-
const CardonaNetworkConfigJSON = `
|
| 5 |
-
{
|
| 6 |
-
"l1Config": {
|
| 7 |
-
"polygonZkEVMAddress": "0xA13Ddb14437A8F34897131367ad3ca78416d6bCa",
|
| 8 |
-
"polygonZkEVMBridgeAddress": "0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582",
|
| 9 |
-
"polygonZkEVMGlobalExitRootAddress": "0xAd1490c248c5d3CbAE399Fd529b79B42984277DF",
|
| 10 |
-
"polTokenAddress": "0x6a7c3F4B0651d6DA389AD1d11D962ea458cDCA70",
|
| 11 |
-
"polygonRollupManagerAddress": "0x32d33D5137a7cFFb54c5Bf8371172bcEc5f310ff",
|
| 12 |
-
"chainId": 11155111
|
| 13 |
-
},
|
| 14 |
-
"genesisBlockNumber": 4789190,
|
| 15 |
-
"root": "0x91dfcdeb628dfdc51f3a2ee38cb17c78581e4e7ff91bcc2e327d24a9dfa46982",
|
| 16 |
-
"genesis": [
|
| 17 |
-
{
|
| 18 |
-
"contractName": "PolygonZkEVMDeployer",
|
| 19 |
-
"balance": "0",
|
| 20 |
-
"nonce": "4",
|
| 21 |
-
"address": "0x36810012486fc134D0679c07f85fe5ba5A087D8C",
|
| 22 |
-
"bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212203e70ce334e8ec9d8d03e87415afd36dce4e82633bd277b08937095a6bd66367764736f6c63430008110033",
|
| 23 |
-
"storage": {
|
| 24 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000ff6250d0e86a2465b0c1bf8e36409503d6a26963"
|
| 25 |
-
}
|
| 26 |
-
},
|
| 27 |
-
{
|
| 28 |
-
"contractName": "ProxyAdmin",
|
| 29 |
-
"balance": "0",
|
| 30 |
-
"nonce": "1",
|
| 31 |
-
"address": "0x85cEB41028B1a5ED2b88E395145344837308b251",
|
| 32 |
-
"bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220372a0e10eebea1b7fa43ae4c976994e6ed01d85eedc3637b83f01d3f06be442064736f6c63430008110033",
|
| 33 |
-
"storage": {
|
| 34 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000dbc6981a11fc2b000c635bfa7c47676b25c87d39"
|
| 35 |
-
}
|
| 36 |
-
},
|
| 37 |
-
{
|
| 38 |
-
"contractName": "PolygonZkEVMBridge implementation",
|
| 39 |
-
"balance": "0",
|
| 40 |
-
"nonce": "1",
|
| 41 |
-
"address": "0x8BD36ca1A55e389335004872aA3C3Be0969D3aA7",
|
| 42 |
-
"bytecode": "0x6080604052600436106200019f5760003560e01c8063647c576c11620000e7578063be5831c71162000089578063dbc169761162000060578063dbc169761462000639578063ee25560b1462000651578063fb570834146200068257600080fd5b8063be5831c714620005ae578063cd58657914620005ea578063d02103ca146200060157600080fd5b80639e34070f11620000be5780639e34070f146200050a578063aaa13cc2146200054f578063bab161bf146200057457600080fd5b8063647c576c146200048657806379e2cf9714620004ab57806381b1c17414620004c357600080fd5b80632d2c9d94116200015157806334ac9cf2116200012857806334ac9cf2146200034b5780633ae05047146200037a5780633e197043146200039257600080fd5b80632d2c9d9414620002765780632dfdf0b5146200029b578063318aee3d14620002c257600080fd5b806322e95f2c116200018657806322e95f2c14620001ef578063240ff378146200023a5780632cffd02e146200025157600080fd5b806315064c9614620001a45780632072f6c514620001d5575b600080fd5b348015620001b157600080fd5b50606854620001c09060ff1681565b60405190151581526020015b60405180910390f35b348015620001e257600080fd5b50620001ed620006a7565b005b348015620001fc57600080fd5b50620002146200020e366004620032db565b62000705565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001cc565b620001ed6200024b36600462003372565b620007a8565b3480156200025e57600080fd5b50620001ed6200027036600462003409565b620009d0565b3480156200028357600080fd5b50620001ed6200029536600462003409565b62000f74565b348015620002a857600080fd5b50620002b360535481565b604051908152602001620001cc565b348015620002cf57600080fd5b5062000319620002e1366004620034ef565b606b6020526000908152604090205463ffffffff811690640100000000900473ffffffffffffffffffffffffffffffffffffffff1682565b6040805163ffffffff909316835273ffffffffffffffffffffffffffffffffffffffff909116602083015201620001cc565b3480156200035857600080fd5b50606c54620002149073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200038757600080fd5b50620002b362001178565b3480156200039f57600080fd5b50620002b3620003b136600462003526565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b3480156200049357600080fd5b50620001ed620004a5366004620035b0565b6200125e565b348015620004b857600080fd5b50620001ed620014ad565b348015620004d057600080fd5b5062000214620004e236600462003600565b606a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200051757600080fd5b50620001c06200052936600462003600565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200055c57600080fd5b50620002146200056e3660046200361a565b620014e7565b3480156200058157600080fd5b506068546200059890610100900463ffffffff1681565b60405163ffffffff9091168152602001620001cc565b348015620005bb57600080fd5b506068546200059890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b620001ed620005fb366004620036ce565b620016d3565b3480156200060e57600080fd5b50606854620002149065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200064657600080fd5b50620001ed62001c37565b3480156200065e57600080fd5b50620002b36200067036600462003600565b60696020526000908152604090205481565b3480156200068f57600080fd5b50620001c0620006a136600462003770565b62001c93565b606c5473ffffffffffffffffffffffffffffffffffffffff163314620006f9576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362001d7c565b565b6040805160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016602080830191909152606084901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602483015282516018818403018152603890920183528151918101919091206000908152606a909152205473ffffffffffffffffffffffffffffffffffffffff165b92915050565b60685460ff1615620007e6576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff8681166101009092041614806200080c5750600263ffffffff861610155b1562000844576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff163388883488886053546040516200089a9998979695949392919062003806565b60405180910390a1620009b8620009b26001606860019054906101000a900463ffffffff16338989348989604051620008d592919062003881565b60405180910390206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b62001e10565b8215620009c957620009c962001f27565b5050505050565b60685460ff161562000a0e576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000a258b8b8b8b8b8b8b8b8b8b8b600062001ffc565b73ffffffffffffffffffffffffffffffffffffffff861662000b01576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff861690859060405162000a7a9190620038e6565b60006040518083038185875af1925050503d806000811462000ab9576040519150601f19603f3d011682016040523d82523d6000602084013e62000abe565b606091505b505090508062000afa576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5062000efc565b60685463ffffffff61010090910481169088160362000b435762000b3d73ffffffffffffffffffffffffffffffffffffffff87168585620021ed565b62000efc565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b166024820152600090603801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152606a90935291205490915073ffffffffffffffffffffffffffffffffffffffff168062000e6e576000808062000c1886880188620039fb565b92509250925060008584848460405162000c329062003292565b62000c409392919062003abd565b8190604051809103906000f590508015801562000c61573d6000803e3d6000fd5b506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b15801562000cd757600080fd5b505af115801562000cec573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180604001604052808e63ffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815250606b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000e5c95949392919062003afa565b60405180910390a15050505062000ef9565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000edf57600080fd5b505af115801562000ef4573d6000803e3d6000fd5b505050505b50505b6040805163ffffffff8c811682528916602082015273ffffffffffffffffffffffffffffffffffffffff88811682840152861660608201526080810185905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a15050505050505050505050565b60685460ff161562000fb2576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000fc98b8b8b8b8b8b8b8b8b8b8b600162001ffc565b60008473ffffffffffffffffffffffffffffffffffffffff1684888a868660405160240162000ffc949392919062003b42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1806b5f200000000000000000000000000000000000000000000000000000000179052516200107f9190620038e6565b60006040518083038185875af1925050503d8060008114620010be576040519150601f19603f3d011682016040523d82523d6000602084013e620010c3565b606091505b5050905080620010ff576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805163ffffffff8d811682528a16602082015273ffffffffffffffffffffffffffffffffffffffff89811682840152871660608201526080810186905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a1505050505050505050505050565b605354600090819081805b602081101562001255578083901c600116600103620011e65760338160208110620011b257620011b262003b8a565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062001213565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806200124c9062003be8565b91505062001183565b50919392505050565b600054610100900460ff16158080156200127f5750600054600160ff909116105b806200129b5750303b1580156200129b575060005460ff166001145b6200132d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200138c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8716027fffffffffffffff0000000000000000000000000000000000000000ffffffffff16176501000000000073ffffffffffffffffffffffffffffffffffffffff8681169190910291909117909155606c80547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905562001443620022c3565b8015620014a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854790100000000000000000000000000000000000000000000000000900463ffffffff16101562000703576200070362001f27565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660248201526000908190603801604051602081830303815290604052805190602001209050600060ff60f81b3083604051806020016200157d9062003292565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052620015c8908d908d908d908d908d9060200162003c23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262001606929160200162003c64565b604051602081830303815290604052805190602001206040516020016200168f94939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101209a9950505050505050505050565b60685460ff161562001711576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200171b62002366565b60685463ffffffff888116610100909204161480620017415750600263ffffffff881610155b1562001779576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060608773ffffffffffffffffffffffffffffffffffffffff8816620017df57883414620017d5576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000925062001ad9565b341562001818576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8089166000908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901562001908576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b158015620018db57600080fd5b505af1158015620018f0573d6000803e3d6000fd5b50505050806020015194508060000151935062001ad7565b85156200191d576200191d898b8989620023db565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa1580156200198b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019b1919062003c97565b9050620019d773ffffffffffffffffffffffffffffffffffffffff8b1633308e620028f9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8c16906370a0823190602401602060405180830381865afa15801562001a45573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6b919062003c97565b905062001a79828262003cb1565b6068548c9850610100900463ffffffff169650935062001a998762002959565b62001aa48c62002a71565b62001aaf8d62002b7e565b60405160200162001ac39392919062003abd565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405162001b1b98979695949392919062003cc7565b60405180910390a162001c0f620009b2600085878f8f8789805190602001206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b861562001c205762001c2062001f27565b5050505062001c2e60018055565b50505050505050565b606c5473ffffffffffffffffffffffffffffffffffffffff16331462001c89576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362002c80565b600084815b602081101562001d6e57600163ffffffff8616821c8116900362001d0a5785816020811062001ccb5762001ccb62003b8a565b60200201358260405160200162001cec929190918252602082015260400190565b60405160208183030381529060405280519060200120915062001d59565b8186826020811062001d205762001d2062003b8a565b602002013560405160200162001d40929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b8062001d658162003be8565b91505062001c98565b50821490505b949350505050565b60685460ff161562001dba576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b80600162001e216020600262003e79565b62001e2d919062003cb1565b6053541062001e68576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060536000815462001e7b9062003be8565b9182905550905060005b602081101562001f17578082901c60011660010362001ebd57826033826020811062001eb55762001eb562003b8a565b015550505050565b6033816020811062001ed35762001ed362003b8a565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808062001f0e9062003be8565b91505062001e85565b5062001f2262003e87565b505050565b6053546068805463ffffffff909216790100000000000000000000000000000000000000000000000000027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179081905573ffffffffffffffffffffffffffffffffffffffff65010000000000909104166333d6247d62001fad62001178565b6040518263ffffffff1660e01b815260040162001fcc91815260200190565b600060405180830381600087803b15801562001fe757600080fd5b505af1158015620014a7573d6000803e3d6000fd5b6200200d8b63ffffffff1662002d10565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101207f257b363200000000000000000000000000000000000000000000000000000000909252606481019190915260009165010000000000900473ffffffffffffffffffffffffffffffffffffffff169063257b3632906084016020604051808303816000875af1158015620020b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020d6919062003c97565b90508060000362002112576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff88811661010090920416146200215c576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606854600090610100900463ffffffff166200217a5750896200217d565b508a5b620021a66200219d848c8c8c8c8c8c8c604051620008d592919062003881565b8f8f8462001c93565b620021dd576040517fe0417cec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262001f229084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262002d75565b600054610100900460ff166200235c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6200070362002e88565b600260015403620023d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001324565b6002600155565b6000620023ec600482848662003eb6565b620023f79162003ee2565b90507f2afa5331000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601620026765760008080808080806200245a896004818d62003eb6565b81019062002469919062003f2b565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614620024dd576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861630146200252d576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a851462002567576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff89811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e1691620026229190620038e6565b6000604051808303816000865af19150503d806000811462002661576040519150601f19603f3d011682016040523d82523d6000602084013e62002666565b606091505b50505050505050505050620009c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c0000000000000000000000000000000000000000000000000000000014620026f2576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080808080806200270a8a6004818e62003eb6565b81019062002719919062003f86565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146200278f576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87163014620027df576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c000000000000000000000000000000000000000000000000000000001790529151918f1691620028a39190620038e6565b6000604051808303816000865af19150503d8060008114620028e2576040519150601f19603f3d011682016040523d82523d6000602084013e620028e7565b606091505b50505050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620014a79085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162002240565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620029dd9190620038e6565b600060405180830381855afa9150503d806000811462002a1a576040519150601f19603f3d011682016040523d82523d6000602084013e62002a1f565b606091505b50915091508162002a66576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062001d74565b62001d748162002f21565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff86169162002af59190620038e6565b600060405180830381855afa9150503d806000811462002b32576040519150601f19603f3d011682016040523d82523d6000602084013e62002b37565b606091505b50915091508162002a66576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062001d74565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162002c019190620038e6565b600060405180830381855afa9150503d806000811462002c3e576040519150601f19603f3d011682016040523d82523d6000602084013e62002c43565b606091505b509150915081801562002c57575080516020145b62002c6457601262001d74565b8080602001905181019062001d74919062004012565b60018055565b60685460ff1662002cbd576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620009c9576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062002dd9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620031119092919063ffffffff16565b80519091501562001f22578080602001905181019062002dfa919062004032565b62001f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162001324565b600054610100900460ff1662002c7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6060604082511062002f435781806020019051810190620007a2919062004052565b8151602003620030d35760005b60208110801562002f9b575082818151811062002f715762002f7162003b8a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562002fb6578062002fad8162003be8565b91505062002f50565b8060000362002ffa57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003018576200301862003891565b6040519080825280601f01601f19166020018201604052801562003043576020820181803683370190505b50905060005b82811015620030cb5784818151811062003067576200306762003b8a565b602001015160f81c60f81b82828151811062003087576200308762003b8a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620030c28162003be8565b91505062003049565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b606062001d748484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051620031489190620038e6565b60006040518083038185875af1925050503d806000811462003187576040519150601f19603f3d011682016040523d82523d6000602084013e6200318c565b606091505b50915091506200319f87838387620031aa565b979650505050505050565b60608315620032455782516000036200323d5773ffffffffffffffffffffffffffffffffffffffff85163b6200323d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001324565b508162001d74565b62001d7483838151156200325c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013249190620040d2565b611b6680620040e883390190565b803563ffffffff811681146200310c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114620032d857600080fd5b50565b60008060408385031215620032ef57600080fd5b620032fa83620032a0565b915060208301356200330c81620032b5565b809150509250929050565b8015158114620032d857600080fd5b60008083601f8401126200333957600080fd5b50813567ffffffffffffffff8111156200335257600080fd5b6020830191508360208285010111156200336b57600080fd5b9250929050565b6000806000806000608086880312156200338b57600080fd5b6200339686620032a0565b94506020860135620033a881620032b5565b93506040860135620033ba8162003317565b9250606086013567ffffffffffffffff811115620033d757600080fd5b620033e58882890162003326565b969995985093965092949392505050565b806104008101831015620007a257600080fd5b60008060008060008060008060008060006105208c8e0312156200342c57600080fd5b620034388d8d620033f6565b9a50620034496104008d01620032a0565b99506104208c013598506104408c013597506200346a6104608d01620032a0565b96506104808c01356200347d81620032b5565b95506200348e6104a08d01620032a0565b94506104c08c0135620034a181620032b5565b93506104e08c013592506105008c013567ffffffffffffffff811115620034c757600080fd5b620034d58e828f0162003326565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200350257600080fd5b81356200350f81620032b5565b9392505050565b60ff81168114620032d857600080fd5b600080600080600080600060e0888a0312156200354257600080fd5b87356200354f8162003516565b96506200355f60208901620032a0565b955060408801356200357181620032b5565b94506200358160608901620032a0565b935060808801356200359381620032b5565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215620035c657600080fd5b620035d184620032a0565b92506020840135620035e381620032b5565b91506040840135620035f581620032b5565b809150509250925092565b6000602082840312156200361357600080fd5b5035919050565b600080600080600080600060a0888a0312156200363657600080fd5b6200364188620032a0565b965060208801356200365381620032b5565b9550604088013567ffffffffffffffff808211156200367157600080fd5b6200367f8b838c0162003326565b909750955060608a01359150808211156200369957600080fd5b50620036a88a828b0162003326565b9094509250506080880135620036be8162003516565b8091505092959891949750929550565b600080600080600080600060c0888a031215620036ea57600080fd5b620036f588620032a0565b965060208801356200370781620032b5565b95506040880135945060608801356200372081620032b5565b93506080880135620037328162003317565b925060a088013567ffffffffffffffff8111156200374f57600080fd5b6200375d8a828b0162003326565b989b979a50959850939692959293505050565b60008060008061046085870312156200378857600080fd5b843593506200379b8660208701620033f6565b9250620037ac6104208601620032a0565b939692955092936104400135925050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600061010060ff8c16835263ffffffff808c16602085015273ffffffffffffffffffffffffffffffffffffffff808c166040860152818b166060860152808a166080860152508760a08501528160c0850152620038678285018789620037bd565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b83811015620038dd578181015183820152602001620038c3565b50506000910152565b60008251620038fa818460208701620038c0565b9190910192915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156200394e576200394e62003891565b604052919050565b600067ffffffffffffffff82111562003973576200397362003891565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620039b157600080fd5b8135620039c8620039c28262003956565b62003904565b818152846020838601011115620039de57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562003a1157600080fd5b833567ffffffffffffffff8082111562003a2a57600080fd5b62003a38878388016200399f565b9450602086013591508082111562003a4f57600080fd5b5062003a5e868287016200399f565b9250506040840135620035f58162003516565b6000815180845262003a8b816020860160208601620038c0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600062003ad2606083018662003a71565b828103602084015262003ae6818662003a71565b91505060ff83166040830152949350505050565b63ffffffff86168152600073ffffffffffffffffffffffffffffffffffffffff8087166020840152808616604084015250608060608301526200319f608083018486620037bd565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff8416602082015260606040820152600062003b80606083018486620037bd565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362003c1c5762003c1c62003bb9565b5060010190565b60608152600062003c39606083018789620037bd565b828103602084015262003c4e818688620037bd565b91505060ff831660408301529695505050505050565b6000835162003c78818460208801620038c0565b83519083019062003c8e818360208801620038c0565b01949350505050565b60006020828403121562003caa57600080fd5b5051919050565b81810381811115620007a257620007a262003bb9565b600061010060ff8b16835263ffffffff808b16602085015273ffffffffffffffffffffffffffffffffffffffff808b166040860152818a1660608601528089166080860152508660a08501528160c085015262003d278285018762003a71565b925080851660e085015250509998505050505050505050565b600181815b8085111562003d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003d835762003d8362003bb9565b8085161562003d9157918102915b93841c939080029062003d45565b509250929050565b60008262003db857506001620007a2565b8162003dc757506000620007a2565b816001811462003de0576002811462003deb5762003e0b565b6001915050620007a2565b60ff84111562003dff5762003dff62003bb9565b50506001821b620007a2565b5060208310610133831016604e8410600b841016171562003e30575081810a620007a2565b62003e3c838362003d40565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003e715762003e7162003bb9565b029392505050565b60006200350f838362003da7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000808585111562003ec757600080fd5b8386111562003ed557600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562003f235780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562003f4757600080fd5b873562003f5481620032b5565b9650602088013562003f6681620032b5565b955060408801359450606088013593506080880135620035938162003516565b600080600080600080600080610100898b03121562003fa457600080fd5b883562003fb181620032b5565b9750602089013562003fc381620032b5565b96506040890135955060608901359450608089013562003fe38162003317565b935060a089013562003ff58162003516565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200402557600080fd5b81516200350f8162003516565b6000602082840312156200404557600080fd5b81516200350f8162003317565b6000602082840312156200406557600080fd5b815167ffffffffffffffff8111156200407d57600080fd5b8201601f810184136200408f57600080fd5b8051620040a0620039c28262003956565b818152856020838501011115620040b657600080fd5b620040c9826020830160208601620038c0565b95945050505050565b6020815260006200350f602083018462003a7156fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220d9b3ca7b13ec80ac58634ddf0ecebe71e209a71f532614949b9e720413f50c8364736f6c63430008110033"
|
| 43 |
-
},
|
| 44 |
-
{
|
| 45 |
-
"contractName": "PolygonZkEVMBridge proxy",
|
| 46 |
-
"balance": "200000000000000000000000000",
|
| 47 |
-
"nonce": "1",
|
| 48 |
-
"address": "0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582",
|
| 49 |
-
"bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461088b565b610135565b61006b6100a33660046108a6565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461088b565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109bb602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161052a565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b61042283610552565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a16101748161059f565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516104cf919061094d565b600060405180830381855af49150503d806000811461050a576040519150601f19603f3d011682016040523d82523d6000602084013e61050f565b606091505b5091509150610520868383876106ab565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b61055b81610753565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8116610642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561074157825160000361073a5773ffffffffffffffffffffffffffffffffffffffff85163b61073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103a2565b508161074b565b61074b838361081e565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6107f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610665565b81511561082e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610969565b803573ffffffffffffffffffffffffffffffffffffffff8116811461088657600080fd5b919050565b60006020828403121561089d57600080fd5b6102b182610862565b6000806000604084860312156108bb57600080fd5b6108c484610862565b9250602084013567ffffffffffffffff808211156108e157600080fd5b818601915086601f8301126108f557600080fd5b81358181111561090457600080fd5b87602082850101111561091657600080fd5b6020830194508093505050509250925092565b60005b8381101561094457818101518382015260200161092c565b50506000910152565b6000825161095f818460208701610929565b9190910192915050565b6020815260008251806020840152610988816040850160208701610929565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1af0d6cb4f1e31496a4c5c1448913bce4bd6ad3a39e47c6f7190c114d6f9bf464736f6c63430008110033",
|
| 50 |
-
"storage": {
|
| 51 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 52 |
-
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 53 |
-
"0x0000000000000000000000000000000000000000000000000000000000000068": "0x00000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa0000000100",
|
| 54 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000085ceb41028b1a5ed2b88e395145344837308b251",
|
| 55 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000008bd36ca1a55e389335004872aa3c3be0969d3aa7"
|
| 56 |
-
}
|
| 57 |
-
},
|
| 58 |
-
{
|
| 59 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 implementation",
|
| 60 |
-
"balance": "0",
|
| 61 |
-
"nonce": "1",
|
| 62 |
-
"address": "0x282a631D9F3Ef04Bf1A44B4C9e8bDC8EB278917f",
|
| 63 |
-
"bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f000000000000000000000000528e26b25a34a4a5d0dbda1d57d318153d2ed58281565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000528e26b25a34a4a5d0dbda1d57d318153d2ed582161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220a187fc278346c1b61c449ea3641002b6eac2bda3351a122a12c35099f933696864736f6c63430008110033"
|
| 64 |
-
},
|
| 65 |
-
{
|
| 66 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 proxy",
|
| 67 |
-
"balance": "0",
|
| 68 |
-
"nonce": "1",
|
| 69 |
-
"address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa",
|
| 70 |
-
"bytecode": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033",
|
| 71 |
-
"storage": {
|
| 72 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000085ceb41028b1a5ed2b88e395145344837308b251",
|
| 73 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000282a631d9f3ef04bf1a44b4c9e8bdc8eb278917f"
|
| 74 |
-
}
|
| 75 |
-
},
|
| 76 |
-
{
|
| 77 |
-
"contractName": "PolygonZkEVMTimelock",
|
| 78 |
-
"balance": "0",
|
| 79 |
-
"nonce": "1",
|
| 80 |
-
"address": "0xdbC6981a11fc2B000c635bFA7C47676b25C87D39",
|
| 81 |
-
"bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c52565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611cc7565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611d09565b6107df565b3480156102be57600080fd5b506102146102cd366004611d75565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e9a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d75565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d75565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611f02565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d75565b610927565b3480156103f457600080fd5b506101f2610403366004611f02565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d75565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d75565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611d09565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f73565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611f02565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004612025565b610d4f565b3480156105db57600080fd5b506103166105ea36600461214e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d75565b610d94565b34801561064057600080fd5b5061025d61064f366004611d75565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611f02565b610e8f565b6101f261068f366004612025565b610eb4565b3480156106a057600080fd5b506103166106af3660046121f8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611244565b6000610728898989898989610ade565b90506107348184611251565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a604051610770969594939291906122a6565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261139e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c8133611435565b600061086c888888888888610ade565b905061087881856114ed565b6108848888888861162a565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122f1565b60405180910390a36108cd8161172e565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611244565b61092283836117d7565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f482826118c7565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb969594939291906122a6565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611244565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611251565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc3612331565b9050602002016020810190610cd89190612360565b8d8d86818110610cea57610cea612331565b905060200201358c8c87818110610d0357610d03612331565b9050602002810190610d15919061237b565b8c8b604051610d29969594939291906122a6565b60405180910390a3610d3a8161240f565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124f7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611244565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611244565b61092283836118c7565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f318133611435565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ed565b60005b8981101561114b5760008b8b8381811061108c5761108c612331565b90506020020160208101906110a19190612360565b905060008a8a848181106110b7576110b7612331565b9050602002013590503660008a8a868181106110d5576110d5612331565b90506020028101906110e7919061237b565b915091506110f78484848461162a565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122f1565b60405180910390a350505050806111449061240f565b9050611070565b506111558161172e565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580159061123257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123291906125be565b1561123d5750600090565b5060025490565b61124e8133611435565b50565b61125a82610927565b156112e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112ef611161565b81101561137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61138881426125e0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114738161197e565b61147e83602061199d565b60405160200161148f929190612617565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612698565b6114f6826108d7565b611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061159e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116549291906126e9565b60006040518083038185875af1925050503d8060008114611691576040519150601f19603f3d011682016040523d82523d6000602084013e611696565b606091505b5050905080611727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b611737816108d7565b6117c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118693390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b606060006119ac8360026126f9565b6119b79060026125e0565b67ffffffffffffffff8111156119cf576119cf611d8e565b6040519080825280601f01601f1916602001820160405280156119f9576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611a3057611a30612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a9357611a93612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611acf8460026126f9565b611ada9060016125e0565b90505b6001811115611b77577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b1b57611b1b612331565b1a60f81b828281518110611b3157611b31612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b7081612710565b9050611add565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611c0457600080fd5b919050565b60008083601f840112611c1b57600080fd5b50813567ffffffffffffffff811115611c3357600080fd5b602083019150836020828501011115611c4b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c6d57600080fd5b611c7688611be0565b965060208801359550604088013567ffffffffffffffff811115611c9957600080fd5b611ca58a828b01611c09565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611cd957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611d2257600080fd5b611d2b87611be0565b955060208701359450604087013567ffffffffffffffff811115611d4e57600080fd5b611d5a89828a01611c09565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0457611e04611d8e565b604052919050565b600082601f830112611e1d57600080fd5b813567ffffffffffffffff811115611e3757611e37611d8e565b611e6860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dbd565b818152846020838601011115611e7d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611eb057600080fd5b611eb985611be0565b9350611ec760208601611be0565b925060408501359150606085013567ffffffffffffffff811115611eea57600080fd5b611ef687828801611e0c565b91505092959194509250565b60008060408385031215611f1557600080fd5b82359150611f2560208401611be0565b90509250929050565b60008083601f840112611f4057600080fd5b50813567ffffffffffffffff811115611f5857600080fd5b6020830191508360208260051b8501011115611c4b57600080fd5b600080600080600080600080600060c08a8c031215611f9157600080fd5b893567ffffffffffffffff80821115611fa957600080fd5b611fb58d838e01611f2e565b909b50995060208c0135915080821115611fce57600080fd5b611fda8d838e01611f2e565b909950975060408c0135915080821115611ff357600080fd5b506120008c828d01611f2e565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561204157600080fd5b883567ffffffffffffffff8082111561205957600080fd5b6120658c838d01611f2e565b909a50985060208b013591508082111561207e57600080fd5b61208a8c838d01611f2e565b909850965060408b01359150808211156120a357600080fd5b506120b08b828c01611f2e565b999c989b509699959896976060870135966080013595509350505050565b600082601f8301126120df57600080fd5b8135602067ffffffffffffffff8211156120fb576120fb611d8e565b8160051b61210a828201611dbd565b928352848101820192828101908785111561212457600080fd5b83870192505b848310156121435782358252918301919083019061212a565b979650505050505050565b600080600080600060a0868803121561216657600080fd5b61216f86611be0565b945061217d60208701611be0565b9350604086013567ffffffffffffffff8082111561219a57600080fd5b6121a689838a016120ce565b945060608801359150808211156121bc57600080fd5b6121c889838a016120ce565b935060808801359150808211156121de57600080fd5b506121eb88828901611e0c565b9150509295509295909350565b600080600080600060a0868803121561221057600080fd5b61221986611be0565b945061222760208701611be0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561225157600080fd5b6121eb88828901611e0c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a0604082015260006122dc60a08301868861225d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061232760608301848661225d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561237257600080fd5b6108f682611be0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123b057600080fd5b83018035915067ffffffffffffffff8211156123cb57600080fd5b602001915036819003821315611c4b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612440576124406123e0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124ea57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126124a057600080fd5b8701858101903567ffffffffffffffff8111156124bc57600080fd5b8036038213156124cb57600080fd5b6124d686828461225d565b9a87019a9550505090840190600101612461565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125455773ffffffffffffffffffffffffffffffffffffffff61253084611be0565b1682526020928301929091019060010161250a565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561257e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125a69082018789612447565b60608401959095525050608001529695505050505050565b6000602082840312156125d057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123e0565b60005b8381101561260e5781810151838201526020016125f6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161264f8160178501602088016125f3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161268c8160288401602088016125f3565b01602801949350505050565b60208152600082518060208401526126b78160408501602087016125f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123e0565b60008161271f5761271f6123e0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206416c4e08f97752b4bb06159524dac058d3dccd8775e57ef1b01505751ebf7af64736f6c63430008110033",
|
| 82 |
-
"storage": {
|
| 83 |
-
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000e10",
|
| 84 |
-
"0xf587dde6f8846415188f807710a3304f72092565918b30307d60efdc8014f20b": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 85 |
-
"0x07020fe9de9b8274d1e6cc0668a6f6344a870f35e5a847590c8069dfa85ac78f": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 86 |
-
"0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 87 |
-
"0xc8e266e0814671642b74f3807affd27009fcc23f713ea92d1743e0ee0c1e7603": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 88 |
-
"0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 89 |
-
"0x9b3efc411c5f69533db363941e091f6f3af8b7e306525413577a56d27e5dbe73": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 90 |
-
"0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 91 |
-
"0xa2001bdd6a5944149e83176d089ee9a8246bd56aecf38fe4d6c66f5fbac18675": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 92 |
-
"0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5"
|
| 93 |
-
}
|
| 94 |
-
},
|
| 95 |
-
{
|
| 96 |
-
"accountName": "keyless Deployer",
|
| 97 |
-
"balance": "0",
|
| 98 |
-
"nonce": "1",
|
| 99 |
-
"address": "0x1754175c450BEbB9B6E14dEe542649c0402A25d2"
|
| 100 |
-
},
|
| 101 |
-
{
|
| 102 |
-
"accountName": "deployer",
|
| 103 |
-
"balance": "100000000000000000000000",
|
| 104 |
-
"nonce": "8",
|
| 105 |
-
"address": "0xff6250d0E86A2465B0C1bF8e36409503d6a26963"
|
| 106 |
-
}
|
| 107 |
-
]
|
| 108 |
-
}
|
| 109 |
-
`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2,6 +2,8 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
|
|
|
|
|
|
| 5 |
"path/filepath"
|
| 6 |
"strings"
|
| 7 |
|
|
@@ -21,6 +24,7 @@
|
|
| 21 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 22 |
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 23 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
|
|
|
|
| 24 |
"github.com/mitchellh/mapstructure"
|
| 25 |
"github.com/spf13/viper"
|
| 26 |
"github.com/urfave/cli/v2"
|
|
@@ -31,7 +35,7 @@
|
|
| 31 |
FlagYes = "yes"
|
| 32 |
// FlagCfg is the flag for cfg.
|
| 33 |
FlagCfg = "cfg"
|
| 34 |
-
// FlagNetwork is the flag for the network name. Valid values: ["
|
| 35 |
FlagNetwork = "network"
|
| 36 |
// FlagCustomNetwork is the flag for the custom network file. This is required if --network=custom
|
| 37 |
FlagCustomNetwork = "custom-network-file"
|
|
@@ -183,3 +187,19 @@
|
|
| 183 |
}
|
| 184 |
return cfg, nil
|
| 185 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
+
"os"
|
| 7 |
"path/filepath"
|
| 8 |
"strings"
|
| 9 |
|
|
|
|
| 24 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 25 |
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 26 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
|
| 27 |
+
"github.com/ethereum/go-ethereum/accounts/keystore"
|
| 28 |
"github.com/mitchellh/mapstructure"
|
| 29 |
"github.com/spf13/viper"
|
| 30 |
"github.com/urfave/cli/v2"
|
|
|
|
| 35 |
FlagYes = "yes"
|
| 36 |
// FlagCfg is the flag for cfg.
|
| 37 |
FlagCfg = "cfg"
|
| 38 |
+
// FlagNetwork is the flag for the network name. Valid values: ["custom"].
|
| 39 |
FlagNetwork = "network"
|
| 40 |
// FlagCustomNetwork is the flag for the custom network file. This is required if --network=custom
|
| 41 |
FlagCustomNetwork = "custom-network-file"
|
|
|
|
| 187 |
}
|
| 188 |
return cfg, nil
|
| 189 |
}
|
| 190 |
+
|
| 191 |
+
// NewKeyFromKeystore creates a private key from a keystore file
|
| 192 |
+
func NewKeyFromKeystore(cfg types.KeystoreFileConfig) (*ecdsa.PrivateKey, error) {
|
| 193 |
+
if cfg.Path == "" && cfg.Password == "" {
|
| 194 |
+
return nil, nil
|
| 195 |
+
}
|
| 196 |
+
keystoreEncrypted, err := os.ReadFile(filepath.Clean(cfg.Path))
|
| 197 |
+
if err != nil {
|
| 198 |
+
return nil, err
|
| 199 |
+
}
|
| 200 |
+
key, err := keystore.DecryptKey(keystoreEncrypted, cfg.Password)
|
| 201 |
+
if err != nil {
|
| 202 |
+
return nil, err
|
| 203 |
+
}
|
| 204 |
+
return key.PrivateKey, nil
|
| 205 |
+
}
|
|
@@ -58,7 +58,7 @@
|
|
| 58 |
},
|
| 59 |
{
|
| 60 |
path: "Synchronizer.L2Synchronization.ReprocessFullBatchOnClose",
|
| 61 |
-
expectedValue:
|
| 62 |
},
|
| 63 |
{
|
| 64 |
path: "Synchronizer.L2Synchronization.CheckLastL2BlockHashOnCloseBatch",
|
|
@@ -174,24 +174,28 @@
|
|
| 174 |
expectedValue: uint64(80000),
|
| 175 |
},
|
| 176 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
path: "Etherman.URL",
|
| 178 |
expectedValue: "http://localhost:8545",
|
| 179 |
},
|
| 180 |
{
|
| 181 |
path: "NetworkConfig.L1Config.L1ChainID",
|
| 182 |
-
expectedValue: uint64(
|
| 183 |
},
|
| 184 |
{
|
| 185 |
path: "NetworkConfig.L1Config.ZkEVMAddr",
|
| 186 |
-
expectedValue: common.HexToAddress("
|
| 187 |
},
|
| 188 |
{
|
| 189 |
path: "NetworkConfig.L1Config.PolAddr",
|
| 190 |
-
expectedValue: common.HexToAddress("
|
| 191 |
},
|
| 192 |
{
|
| 193 |
path: "NetworkConfig.L1Config.GlobalExitRootManagerAddr",
|
| 194 |
-
expectedValue: common.HexToAddress("
|
| 195 |
},
|
| 196 |
{
|
| 197 |
path: "Etherman.MultiGasProvider",
|
|
@@ -547,7 +551,8 @@
|
|
| 547 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 548 |
|
| 549 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 550 |
-
flagSet.String(config.FlagNetwork, "
|
|
|
|
| 551 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 552 |
cfg, err := config.Load(ctx, true)
|
| 553 |
if err != nil {
|
|
@@ -585,7 +590,8 @@
|
|
| 585 |
}()
|
| 586 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 587 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 588 |
-
flagSet.String(config.FlagNetwork, "
|
|
|
|
| 589 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 590 |
|
| 591 |
os.Setenv("ZKEVM_NODE_LOG_OUTPUTS", "a,b,c")
|
|
|
|
| 58 |
},
|
| 59 |
{
|
| 60 |
path: "Synchronizer.L2Synchronization.ReprocessFullBatchOnClose",
|
| 61 |
+
expectedValue: false,
|
| 62 |
},
|
| 63 |
{
|
| 64 |
path: "Synchronizer.L2Synchronization.CheckLastL2BlockHashOnCloseBatch",
|
|
|
|
| 174 |
expectedValue: uint64(80000),
|
| 175 |
},
|
| 176 |
{
|
| 177 |
+
path: "SequenceSender.MaxBatchesForL1",
|
| 178 |
+
expectedValue: uint64(300),
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
path: "Etherman.URL",
|
| 182 |
expectedValue: "http://localhost:8545",
|
| 183 |
},
|
| 184 |
{
|
| 185 |
path: "NetworkConfig.L1Config.L1ChainID",
|
| 186 |
+
expectedValue: uint64(1337),
|
| 187 |
},
|
| 188 |
{
|
| 189 |
path: "NetworkConfig.L1Config.ZkEVMAddr",
|
| 190 |
+
expectedValue: common.HexToAddress("0x8dAF17A20c9DBA35f005b6324F493785D239719d"),
|
| 191 |
},
|
| 192 |
{
|
| 193 |
path: "NetworkConfig.L1Config.PolAddr",
|
| 194 |
+
expectedValue: common.HexToAddress("0x5FbDB2315678afecb367f032d93F642f64180aa3"),
|
| 195 |
},
|
| 196 |
{
|
| 197 |
path: "NetworkConfig.L1Config.GlobalExitRootManagerAddr",
|
| 198 |
+
expectedValue: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"),
|
| 199 |
},
|
| 200 |
{
|
| 201 |
path: "Etherman.MultiGasProvider",
|
|
|
|
| 551 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 552 |
|
| 553 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 554 |
+
flagSet.String(config.FlagNetwork, "custom", "")
|
| 555 |
+
flagSet.String(config.FlagCustomNetwork, "../test/config/test.genesis.config.json", "")
|
| 556 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 557 |
cfg, err := config.Load(ctx, true)
|
| 558 |
if err != nil {
|
|
|
|
| 590 |
}()
|
| 591 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 592 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 593 |
+
flagSet.String(config.FlagNetwork, "custom", "")
|
| 594 |
+
flagSet.String(config.FlagCustomNetwork, "../test/config/test.genesis.config.json", "")
|
| 595 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 596 |
|
| 597 |
os.Setenv("ZKEVM_NODE_LOG_OUTPUTS", "a,b,c")
|
|
@@ -105,7 +105,7 @@
|
|
| 105 |
SyncBlockProtection = "safe" # latest, finalized, safe
|
| 106 |
L1SynchronizationMode = "sequential"
|
| 107 |
L1SyncCheckL2BlockHash = true
|
| 108 |
-
|
| 109 |
[Synchronizer.L1BlockCheck]
|
| 110 |
Enable = true
|
| 111 |
L1SafeBlockPoint = "finalized"
|
|
@@ -129,7 +129,7 @@
|
|
| 129 |
ApplyAfterNumRollupReceived = 10
|
| 130 |
[Synchronizer.L2Synchronization]
|
| 131 |
AcceptEmptyClosedBatches = false
|
| 132 |
-
ReprocessFullBatchOnClose =
|
| 133 |
CheckLastL2BlockHashOnCloseBatch = true
|
| 134 |
|
| 135 |
[Sequencer]
|
|
@@ -169,6 +169,7 @@
|
|
| 169 |
L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
|
| 170 |
PrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"}
|
| 171 |
GasOffset = 80000
|
|
|
|
| 172 |
|
| 173 |
[Aggregator]
|
| 174 |
Host = "0.0.0.0"
|
|
@@ -183,6 +184,10 @@
|
|
| 183 |
GasOffset = 0
|
| 184 |
UpgradeEtrogBatchNumber = 0
|
| 185 |
BatchProofL1BlockConfirmations = 2
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
|
| 187 |
[L2GasPriceSuggester]
|
| 188 |
Type = "follower"
|
|
|
|
| 105 |
SyncBlockProtection = "safe" # latest, finalized, safe
|
| 106 |
L1SynchronizationMode = "sequential"
|
| 107 |
L1SyncCheckL2BlockHash = true
|
| 108 |
+
L1SyncCheckL2BlockNumberhModulus = 600
|
| 109 |
[Synchronizer.L1BlockCheck]
|
| 110 |
Enable = true
|
| 111 |
L1SafeBlockPoint = "finalized"
|
|
|
|
| 129 |
ApplyAfterNumRollupReceived = 10
|
| 130 |
[Synchronizer.L2Synchronization]
|
| 131 |
AcceptEmptyClosedBatches = false
|
| 132 |
+
ReprocessFullBatchOnClose = false
|
| 133 |
CheckLastL2BlockHashOnCloseBatch = true
|
| 134 |
|
| 135 |
[Sequencer]
|
|
|
|
| 169 |
L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
|
| 170 |
PrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"}
|
| 171 |
GasOffset = 80000
|
| 172 |
+
MaxBatchesForL1 = 300
|
| 173 |
|
| 174 |
[Aggregator]
|
| 175 |
Host = "0.0.0.0"
|
|
|
|
| 184 |
GasOffset = 0
|
| 185 |
UpgradeEtrogBatchNumber = 0
|
| 186 |
BatchProofL1BlockConfirmations = 2
|
| 187 |
+
SettlementBackend = "agglayer"
|
| 188 |
+
AggLayerTxTimeout = "5m"
|
| 189 |
+
AggLayerURL = "http://zkevm-agglayer"
|
| 190 |
+
SequencerPrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"}
|
| 191 |
|
| 192 |
[L2GasPriceSuggester]
|
| 193 |
Type = "follower"
|
|
@@ -1,108 +0,0 @@
|
|
| 1 |
-
package config
|
| 2 |
-
|
| 3 |
-
// MainnetNetworkConfigJSON is the hardcoded network configuration to be used for the official mainnet setup
|
| 4 |
-
const MainnetNetworkConfigJSON = `
|
| 5 |
-
{
|
| 6 |
-
"l1Config" : {
|
| 7 |
-
"chainId": 1,
|
| 8 |
-
"polygonZkEVMAddress": "0x519E42c24163192Dca44CD3fBDCEBF6be9130987",
|
| 9 |
-
"polygonRollupManagerAddress": "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2",
|
| 10 |
-
"polTokenAddress": "0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6",
|
| 11 |
-
"polygonZkEVMGlobalExitRootAddress": "0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb"
|
| 12 |
-
},
|
| 13 |
-
"root": "0x3f86b09b43e3e49a41fc20a07579b79eba044253367817d5c241d23c0e2bc5c9",
|
| 14 |
-
"genesisBlockNumber": 16896721,
|
| 15 |
-
"genesis": [
|
| 16 |
-
{
|
| 17 |
-
"contractName": "PolygonZkEVMDeployer",
|
| 18 |
-
"balance": "0",
|
| 19 |
-
"nonce": "4",
|
| 20 |
-
"address": "0xCB19eDdE626906eB1EE52357a27F62dd519608C2",
|
| 21 |
-
"bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212203e70ce334e8ec9d8d03e87415afd36dce4e82633bd277b08937095a6bd66367764736f6c63430008110033",
|
| 22 |
-
"storage": {
|
| 23 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000004c1665d6651ecefa59b9b3041951608468b18891"
|
| 24 |
-
}
|
| 25 |
-
},
|
| 26 |
-
{
|
| 27 |
-
"contractName": "ProxyAdmin",
|
| 28 |
-
"balance": "0",
|
| 29 |
-
"nonce": "1",
|
| 30 |
-
"address": "0x0F99738B2Fc14D77308337f3e2596b63aE7BCC4A",
|
| 31 |
-
"bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220372a0e10eebea1b7fa43ae4c976994e6ed01d85eedc3637b83f01d3f06be442064736f6c63430008110033",
|
| 32 |
-
"storage": {
|
| 33 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000bba0935fa93eb23de7990b47f0d96a8f75766d13"
|
| 34 |
-
}
|
| 35 |
-
},
|
| 36 |
-
{
|
| 37 |
-
"contractName": "PolygonZkEVMBridge implementation",
|
| 38 |
-
"balance": "0",
|
| 39 |
-
"nonce": "1",
|
| 40 |
-
"address": "0x5ac4182A1dd41AeEf465E40B82fd326BF66AB82C",
|
| 41 |
-
"bytecode": "0x6080604052600436106200019f5760003560e01c8063647c576c11620000e7578063be5831c71162000089578063dbc169761162000060578063dbc169761462000639578063ee25560b1462000651578063fb570834146200068257600080fd5b8063be5831c714620005ae578063cd58657914620005ea578063d02103ca146200060157600080fd5b80639e34070f11620000be5780639e34070f146200050a578063aaa13cc2146200054f578063bab161bf146200057457600080fd5b8063647c576c146200048657806379e2cf9714620004ab57806381b1c17414620004c357600080fd5b80632d2c9d94116200015157806334ac9cf2116200012857806334ac9cf2146200034b5780633ae05047146200037a5780633e197043146200039257600080fd5b80632d2c9d9414620002765780632dfdf0b5146200029b578063318aee3d14620002c257600080fd5b806322e95f2c116200018657806322e95f2c14620001ef578063240ff378146200023a5780632cffd02e146200025157600080fd5b806315064c9614620001a45780632072f6c514620001d5575b600080fd5b348015620001b157600080fd5b50606854620001c09060ff1681565b60405190151581526020015b60405180910390f35b348015620001e257600080fd5b50620001ed620006a7565b005b348015620001fc57600080fd5b50620002146200020e366004620032db565b62000705565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001cc565b620001ed6200024b36600462003372565b620007a8565b3480156200025e57600080fd5b50620001ed6200027036600462003409565b620009d0565b3480156200028357600080fd5b50620001ed6200029536600462003409565b62000f74565b348015620002a857600080fd5b50620002b360535481565b604051908152602001620001cc565b348015620002cf57600080fd5b5062000319620002e1366004620034ef565b606b6020526000908152604090205463ffffffff811690640100000000900473ffffffffffffffffffffffffffffffffffffffff1682565b6040805163ffffffff909316835273ffffffffffffffffffffffffffffffffffffffff909116602083015201620001cc565b3480156200035857600080fd5b50606c54620002149073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200038757600080fd5b50620002b362001178565b3480156200039f57600080fd5b50620002b3620003b136600462003526565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b3480156200049357600080fd5b50620001ed620004a5366004620035b0565b6200125e565b348015620004b857600080fd5b50620001ed620014ad565b348015620004d057600080fd5b5062000214620004e236600462003600565b606a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200051757600080fd5b50620001c06200052936600462003600565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200055c57600080fd5b50620002146200056e3660046200361a565b620014e7565b3480156200058157600080fd5b506068546200059890610100900463ffffffff1681565b60405163ffffffff9091168152602001620001cc565b348015620005bb57600080fd5b506068546200059890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b620001ed620005fb366004620036ce565b620016d3565b3480156200060e57600080fd5b50606854620002149065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200064657600080fd5b50620001ed62001c37565b3480156200065e57600080fd5b50620002b36200067036600462003600565b60696020526000908152604090205481565b3480156200068f57600080fd5b50620001c0620006a136600462003770565b62001c93565b606c5473ffffffffffffffffffffffffffffffffffffffff163314620006f9576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362001d7c565b565b6040805160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016602080830191909152606084901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602483015282516018818403018152603890920183528151918101919091206000908152606a909152205473ffffffffffffffffffffffffffffffffffffffff165b92915050565b60685460ff1615620007e6576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff8681166101009092041614806200080c5750600263ffffffff861610155b1562000844576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff163388883488886053546040516200089a9998979695949392919062003806565b60405180910390a1620009b8620009b26001606860019054906101000a900463ffffffff16338989348989604051620008d592919062003881565b60405180910390206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b62001e10565b8215620009c957620009c962001f27565b5050505050565b60685460ff161562000a0e576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000a258b8b8b8b8b8b8b8b8b8b8b600062001ffc565b73ffffffffffffffffffffffffffffffffffffffff861662000b01576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff861690859060405162000a7a9190620038e6565b60006040518083038185875af1925050503d806000811462000ab9576040519150601f19603f3d011682016040523d82523d6000602084013e62000abe565b606091505b505090508062000afa576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5062000efc565b60685463ffffffff61010090910481169088160362000b435762000b3d73ffffffffffffffffffffffffffffffffffffffff87168585620021ed565b62000efc565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b166024820152600090603801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152606a90935291205490915073ffffffffffffffffffffffffffffffffffffffff168062000e6e576000808062000c1886880188620039fb565b92509250925060008584848460405162000c329062003292565b62000c409392919062003abd565b8190604051809103906000f590508015801562000c61573d6000803e3d6000fd5b506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b15801562000cd757600080fd5b505af115801562000cec573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180604001604052808e63ffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815250606b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000e5c95949392919062003afa565b60405180910390a15050505062000ef9565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000edf57600080fd5b505af115801562000ef4573d6000803e3d6000fd5b505050505b50505b6040805163ffffffff8c811682528916602082015273ffffffffffffffffffffffffffffffffffffffff88811682840152861660608201526080810185905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a15050505050505050505050565b60685460ff161562000fb2576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000fc98b8b8b8b8b8b8b8b8b8b8b600162001ffc565b60008473ffffffffffffffffffffffffffffffffffffffff1684888a868660405160240162000ffc949392919062003b42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1806b5f200000000000000000000000000000000000000000000000000000000179052516200107f9190620038e6565b60006040518083038185875af1925050503d8060008114620010be576040519150601f19603f3d011682016040523d82523d6000602084013e620010c3565b606091505b5050905080620010ff576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805163ffffffff8d811682528a16602082015273ffffffffffffffffffffffffffffffffffffffff89811682840152871660608201526080810186905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a1505050505050505050505050565b605354600090819081805b602081101562001255578083901c600116600103620011e65760338160208110620011b257620011b262003b8a565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062001213565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806200124c9062003be8565b91505062001183565b50919392505050565b600054610100900460ff16158080156200127f5750600054600160ff909116105b806200129b5750303b1580156200129b575060005460ff166001145b6200132d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200138c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8716027fffffffffffffff0000000000000000000000000000000000000000ffffffffff16176501000000000073ffffffffffffffffffffffffffffffffffffffff8681169190910291909117909155606c80547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905562001443620022c3565b8015620014a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854790100000000000000000000000000000000000000000000000000900463ffffffff16101562000703576200070362001f27565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660248201526000908190603801604051602081830303815290604052805190602001209050600060ff60f81b3083604051806020016200157d9062003292565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052620015c8908d908d908d908d908d9060200162003c23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262001606929160200162003c64565b604051602081830303815290604052805190602001206040516020016200168f94939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101209a9950505050505050505050565b60685460ff161562001711576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200171b62002366565b60685463ffffffff888116610100909204161480620017415750600263ffffffff881610155b1562001779576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060608773ffffffffffffffffffffffffffffffffffffffff8816620017df57883414620017d5576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000925062001ad9565b341562001818576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8089166000908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901562001908576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b158015620018db57600080fd5b505af1158015620018f0573d6000803e3d6000fd5b50505050806020015194508060000151935062001ad7565b85156200191d576200191d898b8989620023db565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa1580156200198b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019b1919062003c97565b9050620019d773ffffffffffffffffffffffffffffffffffffffff8b1633308e620028f9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8c16906370a0823190602401602060405180830381865afa15801562001a45573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6b919062003c97565b905062001a79828262003cb1565b6068548c9850610100900463ffffffff169650935062001a998762002959565b62001aa48c62002a71565b62001aaf8d62002b7e565b60405160200162001ac39392919062003abd565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405162001b1b98979695949392919062003cc7565b60405180910390a162001c0f620009b2600085878f8f8789805190602001206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b861562001c205762001c2062001f27565b5050505062001c2e60018055565b50505050505050565b606c5473ffffffffffffffffffffffffffffffffffffffff16331462001c89576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362002c80565b600084815b602081101562001d6e57600163ffffffff8616821c8116900362001d0a5785816020811062001ccb5762001ccb62003b8a565b60200201358260405160200162001cec929190918252602082015260400190565b60405160208183030381529060405280519060200120915062001d59565b8186826020811062001d205762001d2062003b8a565b602002013560405160200162001d40929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b8062001d658162003be8565b91505062001c98565b50821490505b949350505050565b60685460ff161562001dba576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b80600162001e216020600262003e79565b62001e2d919062003cb1565b6053541062001e68576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060536000815462001e7b9062003be8565b9182905550905060005b602081101562001f17578082901c60011660010362001ebd57826033826020811062001eb55762001eb562003b8a565b015550505050565b6033816020811062001ed35762001ed362003b8a565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808062001f0e9062003be8565b91505062001e85565b5062001f2262003e87565b505050565b6053546068805463ffffffff909216790100000000000000000000000000000000000000000000000000027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179081905573ffffffffffffffffffffffffffffffffffffffff65010000000000909104166333d6247d62001fad62001178565b6040518263ffffffff1660e01b815260040162001fcc91815260200190565b600060405180830381600087803b15801562001fe757600080fd5b505af1158015620014a7573d6000803e3d6000fd5b6200200d8b63ffffffff1662002d10565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101207f257b363200000000000000000000000000000000000000000000000000000000909252606481019190915260009165010000000000900473ffffffffffffffffffffffffffffffffffffffff169063257b3632906084016020604051808303816000875af1158015620020b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020d6919062003c97565b90508060000362002112576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff88811661010090920416146200215c576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606854600090610100900463ffffffff166200217a5750896200217d565b508a5b620021a66200219d848c8c8c8c8c8c8c604051620008d592919062003881565b8f8f8462001c93565b620021dd576040517fe0417cec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262001f229084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262002d75565b600054610100900460ff166200235c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6200070362002e88565b600260015403620023d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001324565b6002600155565b6000620023ec600482848662003eb6565b620023f79162003ee2565b90507f2afa5331000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601620026765760008080808080806200245a896004818d62003eb6565b81019062002469919062003f2b565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614620024dd576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861630146200252d576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a851462002567576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff89811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e1691620026229190620038e6565b6000604051808303816000865af19150503d806000811462002661576040519150601f19603f3d011682016040523d82523d6000602084013e62002666565b606091505b50505050505050505050620009c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c0000000000000000000000000000000000000000000000000000000014620026f2576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080808080806200270a8a6004818e62003eb6565b81019062002719919062003f86565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146200278f576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87163014620027df576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c000000000000000000000000000000000000000000000000000000001790529151918f1691620028a39190620038e6565b6000604051808303816000865af19150503d8060008114620028e2576040519150601f19603f3d011682016040523d82523d6000602084013e620028e7565b606091505b50505050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620014a79085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162002240565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620029dd9190620038e6565b600060405180830381855afa9150503d806000811462002a1a576040519150601f19603f3d011682016040523d82523d6000602084013e62002a1f565b606091505b50915091508162002a66576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062001d74565b62001d748162002f21565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff86169162002af59190620038e6565b600060405180830381855afa9150503d806000811462002b32576040519150601f19603f3d011682016040523d82523d6000602084013e62002b37565b606091505b50915091508162002a66576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062001d74565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162002c019190620038e6565b600060405180830381855afa9150503d806000811462002c3e576040519150601f19603f3d011682016040523d82523d6000602084013e62002c43565b606091505b509150915081801562002c57575080516020145b62002c6457601262001d74565b8080602001905181019062001d74919062004012565b60018055565b60685460ff1662002cbd576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620009c9576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062002dd9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620031119092919063ffffffff16565b80519091501562001f22578080602001905181019062002dfa919062004032565b62001f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162001324565b600054610100900460ff1662002c7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6060604082511062002f435781806020019051810190620007a2919062004052565b8151602003620030d35760005b60208110801562002f9b575082818151811062002f715762002f7162003b8a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562002fb6578062002fad8162003be8565b91505062002f50565b8060000362002ffa57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003018576200301862003891565b6040519080825280601f01601f19166020018201604052801562003043576020820181803683370190505b50905060005b82811015620030cb5784818151811062003067576200306762003b8a565b602001015160f81c60f81b82828151811062003087576200308762003b8a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620030c28162003be8565b91505062003049565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b606062001d748484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051620031489190620038e6565b60006040518083038185875af1925050503d806000811462003187576040519150601f19603f3d011682016040523d82523d6000602084013e6200318c565b606091505b50915091506200319f87838387620031aa565b979650505050505050565b60608315620032455782516000036200323d5773ffffffffffffffffffffffffffffffffffffffff85163b6200323d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001324565b508162001d74565b62001d7483838151156200325c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013249190620040d2565b611b6680620040e883390190565b803563ffffffff811681146200310c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114620032d857600080fd5b50565b60008060408385031215620032ef57600080fd5b620032fa83620032a0565b915060208301356200330c81620032b5565b809150509250929050565b8015158114620032d857600080fd5b60008083601f8401126200333957600080fd5b50813567ffffffffffffffff8111156200335257600080fd5b6020830191508360208285010111156200336b57600080fd5b9250929050565b6000806000806000608086880312156200338b57600080fd5b6200339686620032a0565b94506020860135620033a881620032b5565b93506040860135620033ba8162003317565b9250606086013567ffffffffffffffff811115620033d757600080fd5b620033e58882890162003326565b969995985093965092949392505050565b806104008101831015620007a257600080fd5b60008060008060008060008060008060006105208c8e0312156200342c57600080fd5b620034388d8d620033f6565b9a50620034496104008d01620032a0565b99506104208c013598506104408c013597506200346a6104608d01620032a0565b96506104808c01356200347d81620032b5565b95506200348e6104a08d01620032a0565b94506104c08c0135620034a181620032b5565b93506104e08c013592506105008c013567ffffffffffffffff811115620034c757600080fd5b620034d58e828f0162003326565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200350257600080fd5b81356200350f81620032b5565b9392505050565b60ff81168114620032d857600080fd5b600080600080600080600060e0888a0312156200354257600080fd5b87356200354f8162003516565b96506200355f60208901620032a0565b955060408801356200357181620032b5565b94506200358160608901620032a0565b935060808801356200359381620032b5565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215620035c657600080fd5b620035d184620032a0565b92506020840135620035e381620032b5565b91506040840135620035f581620032b5565b809150509250925092565b6000602082840312156200361357600080fd5b5035919050565b600080600080600080600060a0888a0312156200363657600080fd5b6200364188620032a0565b965060208801356200365381620032b5565b9550604088013567ffffffffffffffff808211156200367157600080fd5b6200367f8b838c0162003326565b909750955060608a01359150808211156200369957600080fd5b50620036a88a828b0162003326565b9094509250506080880135620036be8162003516565b8091505092959891949750929550565b600080600080600080600060c0888a031215620036ea57600080fd5b620036f588620032a0565b965060208801356200370781620032b5565b95506040880135945060608801356200372081620032b5565b93506080880135620037328162003317565b925060a088013567ffffffffffffffff8111156200374f57600080fd5b6200375d8a828b0162003326565b989b979a50959850939692959293505050565b60008060008061046085870312156200378857600080fd5b843593506200379b8660208701620033f6565b9250620037ac6104208601620032a0565b939692955092936104400135925050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600061010060ff8c16835263ffffffff808c16602085015273ffffffffffffffffffffffffffffffffffffffff808c166040860152818b166060860152808a166080860152508760a08501528160c0850152620038678285018789620037bd565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b83811015620038dd578181015183820152602001620038c3565b50506000910152565b60008251620038fa818460208701620038c0565b9190910192915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156200394e576200394e62003891565b604052919050565b600067ffffffffffffffff82111562003973576200397362003891565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620039b157600080fd5b8135620039c8620039c28262003956565b62003904565b818152846020838601011115620039de57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562003a1157600080fd5b833567ffffffffffffffff8082111562003a2a57600080fd5b62003a38878388016200399f565b9450602086013591508082111562003a4f57600080fd5b5062003a5e868287016200399f565b9250506040840135620035f58162003516565b6000815180845262003a8b816020860160208601620038c0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600062003ad2606083018662003a71565b828103602084015262003ae6818662003a71565b91505060ff83166040830152949350505050565b63ffffffff86168152600073ffffffffffffffffffffffffffffffffffffffff8087166020840152808616604084015250608060608301526200319f608083018486620037bd565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff8416602082015260606040820152600062003b80606083018486620037bd565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362003c1c5762003c1c62003bb9565b5060010190565b60608152600062003c39606083018789620037bd565b828103602084015262003c4e818688620037bd565b91505060ff831660408301529695505050505050565b6000835162003c78818460208801620038c0565b83519083019062003c8e818360208801620038c0565b01949350505050565b60006020828403121562003caa57600080fd5b5051919050565b81810381811115620007a257620007a262003bb9565b600061010060ff8b16835263ffffffff808b16602085015273ffffffffffffffffffffffffffffffffffffffff808b166040860152818a1660608601528089166080860152508660a08501528160c085015262003d278285018762003a71565b925080851660e085015250509998505050505050505050565b600181815b8085111562003d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003d835762003d8362003bb9565b8085161562003d9157918102915b93841c939080029062003d45565b509250929050565b60008262003db857506001620007a2565b8162003dc757506000620007a2565b816001811462003de0576002811462003deb5762003e0b565b6001915050620007a2565b60ff84111562003dff5762003dff62003bb9565b50506001821b620007a2565b5060208310610133831016604e8410600b841016171562003e30575081810a620007a2565b62003e3c838362003d40565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003e715762003e7162003bb9565b029392505050565b60006200350f838362003da7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000808585111562003ec757600080fd5b8386111562003ed557600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562003f235780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562003f4757600080fd5b873562003f5481620032b5565b9650602088013562003f6681620032b5565b955060408801359450606088013593506080880135620035938162003516565b600080600080600080600080610100898b03121562003fa457600080fd5b883562003fb181620032b5565b9750602089013562003fc381620032b5565b96506040890135955060608901359450608089013562003fe38162003317565b935060a089013562003ff58162003516565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200402557600080fd5b81516200350f8162003516565b6000602082840312156200404557600080fd5b81516200350f8162003317565b6000602082840312156200406557600080fd5b815167ffffffffffffffff8111156200407d57600080fd5b8201601f810184136200408f57600080fd5b8051620040a0620039c28262003956565b818152856020838501011115620040b657600080fd5b620040c9826020830160208601620038c0565b95945050505050565b6020815260006200350f602083018462003a7156fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220d9b3ca7b13ec80ac58634ddf0ecebe71e209a71f532614949b9e720413f50c8364736f6c63430008110033"
|
| 42 |
-
},
|
| 43 |
-
{
|
| 44 |
-
"contractName": "PolygonZkEVMBridge proxy",
|
| 45 |
-
"balance": "200000000000000000000000000",
|
| 46 |
-
"nonce": "1",
|
| 47 |
-
"address": "0x2a3DD3EB832aF982ec71669E178424b10Dca2EDe",
|
| 48 |
-
"bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461088b565b610135565b61006b6100a33660046108a6565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461088b565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109bb602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161052a565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b61042283610552565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a16101748161059f565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516104cf919061094d565b600060405180830381855af49150503d806000811461050a576040519150601f19603f3d011682016040523d82523d6000602084013e61050f565b606091505b5091509150610520868383876106ab565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b61055b81610753565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8116610642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561074157825160000361073a5773ffffffffffffffffffffffffffffffffffffffff85163b61073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103a2565b508161074b565b61074b838361081e565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6107f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610665565b81511561082e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610969565b803573ffffffffffffffffffffffffffffffffffffffff8116811461088657600080fd5b919050565b60006020828403121561089d57600080fd5b6102b182610862565b6000806000604084860312156108bb57600080fd5b6108c484610862565b9250602084013567ffffffffffffffff808211156108e157600080fd5b818601915086601f8301126108f557600080fd5b81358181111561090457600080fd5b87602082850101111561091657600080fd5b6020830194508093505050509250925092565b60005b8381101561094457818101518382015260200161092c565b50506000910152565b6000825161095f818460208701610929565b9190910192915050565b6020815260008251806020840152610988816040850160208701610929565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1af0d6cb4f1e31496a4c5c1448913bce4bd6ad3a39e47c6f7190c114d6f9bf464736f6c63430008110033",
|
| 49 |
-
"storage": {
|
| 50 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 51 |
-
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 52 |
-
"0x0000000000000000000000000000000000000000000000000000000000000068": "0x00000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa0000000100",
|
| 53 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000000f99738b2fc14d77308337f3e2596b63ae7bcc4a",
|
| 54 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000005ac4182a1dd41aeef465e40b82fd326bf66ab82c"
|
| 55 |
-
}
|
| 56 |
-
},
|
| 57 |
-
{
|
| 58 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 implementation",
|
| 59 |
-
"balance": "0",
|
| 60 |
-
"nonce": "1",
|
| 61 |
-
"address": "0x0200143Fa295EE4dffEF22eE2616c2E008D81688",
|
| 62 |
-
"bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f0000000000000000000000002a3dd3eb832af982ec71669e178424b10dca2ede81565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000002a3dd3eb832af982ec71669e178424b10dca2ede161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220a187fc278346c1b61c449ea3641002b6eac2bda3351a122a12c35099f933696864736f6c63430008110033"
|
| 63 |
-
},
|
| 64 |
-
{
|
| 65 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 proxy",
|
| 66 |
-
"balance": "0",
|
| 67 |
-
"nonce": "1",
|
| 68 |
-
"address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa",
|
| 69 |
-
"bytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ca565b610118565b61005b6100933660046106e5565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ca565b61020b565b3480156100f557600080fd5b506100ad610235565b610106610292565b610116610111610331565b61033b565b565b61012061035f565b6001600160a01b0316336001600160a01b031614156101575761015481604051806020016040528060008152506000610392565b50565b6101546100fe565b61016761035f565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610392915050565b505050565b6101c36100fe565b60006101da61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb610331565b905090565b6102086100fe565b90565b61021361035f565b6001600160a01b0316336001600160a01b0316141561015757610154816103f1565b600061023f61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb61035f565b606061028583836040518060600160405280602781526020016107e460279139610445565b9392505050565b3b151590565b61029a61035f565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb610519565b3660008037600080366000845af43d6000803e80801561035a573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b61039b83610541565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103dc5750805b156101c3576103eb8383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61041a61035f565b604080516001600160a01b03928316815291841660208301520160405180910390a1610154816105e9565b6060833b6104a45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610328565b600080856001600160a01b0316856040516104bf9190610794565b600060405180830381855af49150503d80600081146104fa576040519150601f19603f3d011682016040523d82523d6000602084013e6104ff565b606091505b509150915061050f828286610675565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610383565b803b6105a55760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610328565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b03811661064e5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610328565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105c8565b60608315610684575081610285565b8251156106945782518084602001fd5b8160405162461bcd60e51b815260040161032891906107b0565b80356001600160a01b03811681146106c557600080fd5b919050565b6000602082840312156106dc57600080fd5b610285826106ae565b6000806000604084860312156106fa57600080fd5b610703846106ae565b9250602084013567ffffffffffffffff8082111561072057600080fd5b818601915086601f83011261073457600080fd5b81358181111561074357600080fd5b87602082850101111561075557600080fd5b6020830194508093505050509250925092565b60005b8381101561078357818101518382015260200161076b565b838111156103eb5750506000910152565b600082516107a6818460208701610768565b9190910192915050565b60208152600082518060208401526107cf816040850160208701610768565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204675187caf3a43285d9a2c1844a981e977bd52a85ff073e7fc649f73847d70a464736f6c63430008090033",
|
| 70 |
-
"storage": {
|
| 71 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000000f99738b2fc14d77308337f3e2596b63ae7bcc4a",
|
| 72 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000000200143fa295ee4dffef22ee2616c2e008d81688"
|
| 73 |
-
}
|
| 74 |
-
},
|
| 75 |
-
{
|
| 76 |
-
"contractName": "PolygonZkEVMTimelock",
|
| 77 |
-
"balance": "0",
|
| 78 |
-
"nonce": "1",
|
| 79 |
-
"address": "0xBBa0935Fa93Eb23de7990b47F0D96a8f75766d13",
|
| 80 |
-
"bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c52565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611cc7565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611d09565b6107df565b3480156102be57600080fd5b506102146102cd366004611d75565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e9a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d75565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d75565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611f02565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d75565b610927565b3480156103f457600080fd5b506101f2610403366004611f02565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d75565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d75565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611d09565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f73565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611f02565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004612025565b610d4f565b3480156105db57600080fd5b506103166105ea36600461214e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d75565b610d94565b34801561064057600080fd5b5061025d61064f366004611d75565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611f02565b610e8f565b6101f261068f366004612025565b610eb4565b3480156106a057600080fd5b506103166106af3660046121f8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611244565b6000610728898989898989610ade565b90506107348184611251565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a604051610770969594939291906122a6565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261139e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c8133611435565b600061086c888888888888610ade565b905061087881856114ed565b6108848888888861162a565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122f1565b60405180910390a36108cd8161172e565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611244565b61092283836117d7565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f482826118c7565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb969594939291906122a6565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611244565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611251565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc3612331565b9050602002016020810190610cd89190612360565b8d8d86818110610cea57610cea612331565b905060200201358c8c87818110610d0357610d03612331565b9050602002810190610d15919061237b565b8c8b604051610d29969594939291906122a6565b60405180910390a3610d3a8161240f565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124f7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611244565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611244565b61092283836118c7565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f318133611435565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ed565b60005b8981101561114b5760008b8b8381811061108c5761108c612331565b90506020020160208101906110a19190612360565b905060008a8a848181106110b7576110b7612331565b9050602002013590503660008a8a868181106110d5576110d5612331565b90506020028101906110e7919061237b565b915091506110f78484848461162a565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122f1565b60405180910390a350505050806111449061240f565b9050611070565b506111558161172e565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580159061123257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123291906125be565b1561123d5750600090565b5060025490565b61124e8133611435565b50565b61125a82610927565b156112e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112ef611161565b81101561137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61138881426125e0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114738161197e565b61147e83602061199d565b60405160200161148f929190612617565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612698565b6114f6826108d7565b611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061159e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116549291906126e9565b60006040518083038185875af1925050503d8060008114611691576040519150601f19603f3d011682016040523d82523d6000602084013e611696565b606091505b5050905080611727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b611737816108d7565b6117c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118693390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b606060006119ac8360026126f9565b6119b79060026125e0565b67ffffffffffffffff8111156119cf576119cf611d8e565b6040519080825280601f01601f1916602001820160405280156119f9576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611a3057611a30612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a9357611a93612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611acf8460026126f9565b611ada9060016125e0565b90505b6001811115611b77577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b1b57611b1b612331565b1a60f81b828281518110611b3157611b31612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b7081612710565b9050611add565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611c0457600080fd5b919050565b60008083601f840112611c1b57600080fd5b50813567ffffffffffffffff811115611c3357600080fd5b602083019150836020828501011115611c4b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c6d57600080fd5b611c7688611be0565b965060208801359550604088013567ffffffffffffffff811115611c9957600080fd5b611ca58a828b01611c09565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611cd957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611d2257600080fd5b611d2b87611be0565b955060208701359450604087013567ffffffffffffffff811115611d4e57600080fd5b611d5a89828a01611c09565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0457611e04611d8e565b604052919050565b600082601f830112611e1d57600080fd5b813567ffffffffffffffff811115611e3757611e37611d8e565b611e6860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dbd565b818152846020838601011115611e7d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611eb057600080fd5b611eb985611be0565b9350611ec760208601611be0565b925060408501359150606085013567ffffffffffffffff811115611eea57600080fd5b611ef687828801611e0c565b91505092959194509250565b60008060408385031215611f1557600080fd5b82359150611f2560208401611be0565b90509250929050565b60008083601f840112611f4057600080fd5b50813567ffffffffffffffff811115611f5857600080fd5b6020830191508360208260051b8501011115611c4b57600080fd5b600080600080600080600080600060c08a8c031215611f9157600080fd5b893567ffffffffffffffff80821115611fa957600080fd5b611fb58d838e01611f2e565b909b50995060208c0135915080821115611fce57600080fd5b611fda8d838e01611f2e565b909950975060408c0135915080821115611ff357600080fd5b506120008c828d01611f2e565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561204157600080fd5b883567ffffffffffffffff8082111561205957600080fd5b6120658c838d01611f2e565b909a50985060208b013591508082111561207e57600080fd5b61208a8c838d01611f2e565b909850965060408b01359150808211156120a357600080fd5b506120b08b828c01611f2e565b999c989b509699959896976060870135966080013595509350505050565b600082601f8301126120df57600080fd5b8135602067ffffffffffffffff8211156120fb576120fb611d8e565b8160051b61210a828201611dbd565b928352848101820192828101908785111561212457600080fd5b83870192505b848310156121435782358252918301919083019061212a565b979650505050505050565b600080600080600060a0868803121561216657600080fd5b61216f86611be0565b945061217d60208701611be0565b9350604086013567ffffffffffffffff8082111561219a57600080fd5b6121a689838a016120ce565b945060608801359150808211156121bc57600080fd5b6121c889838a016120ce565b935060808801359150808211156121de57600080fd5b506121eb88828901611e0c565b9150509295509295909350565b600080600080600060a0868803121561221057600080fd5b61221986611be0565b945061222760208701611be0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561225157600080fd5b6121eb88828901611e0c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a0604082015260006122dc60a08301868861225d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061232760608301848661225d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561237257600080fd5b6108f682611be0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123b057600080fd5b83018035915067ffffffffffffffff8211156123cb57600080fd5b602001915036819003821315611c4b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612440576124406123e0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124ea57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126124a057600080fd5b8701858101903567ffffffffffffffff8111156124bc57600080fd5b8036038213156124cb57600080fd5b6124d686828461225d565b9a87019a9550505090840190600101612461565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125455773ffffffffffffffffffffffffffffffffffffffff61253084611be0565b1682526020928301929091019060010161250a565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561257e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125a69082018789612447565b60608401959095525050608001529695505050505050565b6000602082840312156125d057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123e0565b60005b8381101561260e5781810151838201526020016125f6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161264f8160178501602088016125f3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161268c8160288401602088016125f3565b01602801949350505050565b60208152600082518060208401526126b78160408501602087016125f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123e0565b60008161271f5761271f6123e0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206416c4e08f97752b4bb06159524dac058d3dccd8775e57ef1b01505751ebf7af64736f6c63430008110033",
|
| 81 |
-
"storage": {
|
| 82 |
-
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000d2f00",
|
| 83 |
-
"0x33d4aa03df3f12c4f615b40676f67fdafecd3edb5a9c0ca2a47a923dae33a023": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 84 |
-
"0x9fa2d8034dbcb437bee38d61fbd100910e1342ffc07f128aa1b8e6790b7f3f68": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 85 |
-
"0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 86 |
-
"0x531a7c25761aa4b0f2310edca9bb25e1e3ceb49ad4b0422aec866b3ce7567c87": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 87 |
-
"0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 88 |
-
"0xedbedc78c4240c7613622a35de050b48bd6c6d9a31b3d485b68fbbed54a4802d": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 89 |
-
"0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 90 |
-
"0x76616448da8d124a07383c26a6b2433b3259de946aa40f51524ec96ee05e871a": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 91 |
-
"0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5"
|
| 92 |
-
}
|
| 93 |
-
},
|
| 94 |
-
{
|
| 95 |
-
"accountName": "keyless Deployer",
|
| 96 |
-
"balance": "0",
|
| 97 |
-
"nonce": "1",
|
| 98 |
-
"address": "0x9d90066e7478496e2284E54c3548106bb4F90E50"
|
| 99 |
-
},
|
| 100 |
-
{
|
| 101 |
-
"accountName": "deployer",
|
| 102 |
-
"balance": "0",
|
| 103 |
-
"nonce": "8",
|
| 104 |
-
"address": "0x4c1665d6651ecEfa59B9B3041951608468b18891"
|
| 105 |
-
}
|
| 106 |
-
]
|
| 107 |
-
}
|
| 108 |
-
`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -25,17 +25,16 @@
|
|
| 25 |
|
| 26 |
type network string
|
| 27 |
|
| 28 |
-
const mainnet network = "mainnet"
|
| 29 |
-
const testnet network = "testnet"
|
| 30 |
-
const cardona network = "cardona"
|
| 31 |
const custom network = "custom"
|
| 32 |
|
| 33 |
// GenesisFromJSON is the config file for network_custom
|
| 34 |
type GenesisFromJSON struct {
|
| 35 |
// L1: root hash of the genesis block
|
| 36 |
Root string `json:"root"`
|
| 37 |
-
// L1: block number
|
| 38 |
-
|
|
|
|
|
|
|
| 39 |
// L2: List of states contracts used to populate merkle tree at initial state
|
| 40 |
Genesis []genesisAccountFromJSON `json:"genesis"`
|
| 41 |
// L1: configuration of the network
|
|
@@ -60,12 +59,6 @@
|
|
| 60 |
func (cfg *Config) loadNetworkConfig(ctx *cli.Context) {
|
| 61 |
var networkJSON string
|
| 62 |
switch ctx.String(FlagNetwork) {
|
| 63 |
-
case string(mainnet):
|
| 64 |
-
networkJSON = MainnetNetworkConfigJSON
|
| 65 |
-
case string(testnet):
|
| 66 |
-
networkJSON = TestnetNetworkConfigJSON
|
| 67 |
-
case string(cardona):
|
| 68 |
-
networkJSON = CardonaNetworkConfigJSON
|
| 69 |
case string(custom):
|
| 70 |
var err error
|
| 71 |
cfgPath := ctx.String(FlagCustomNetwork)
|
|
@@ -74,7 +67,7 @@
|
|
| 74 |
panic(err.Error())
|
| 75 |
}
|
| 76 |
default:
|
| 77 |
-
log.Fatalf("unsupported --network value. Must be
|
| 78 |
}
|
| 79 |
config, err := LoadGenesisFromJSONString(networkJSON)
|
| 80 |
if err != nil {
|
|
@@ -122,9 +115,10 @@
|
|
| 122 |
|
| 123 |
cfg.L1Config = cfgJSON.L1Config
|
| 124 |
cfg.Genesis = state.Genesis{
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
|
|
|
| 128 |
}
|
| 129 |
|
| 130 |
for _, account := range cfgJSON.Genesis {
|
|
|
|
| 25 |
|
| 26 |
type network string
|
| 27 |
|
|
|
|
|
|
|
|
|
|
| 28 |
const custom network = "custom"
|
| 29 |
|
| 30 |
// GenesisFromJSON is the config file for network_custom
|
| 31 |
type GenesisFromJSON struct {
|
| 32 |
// L1: root hash of the genesis block
|
| 33 |
Root string `json:"root"`
|
| 34 |
+
// L1: block number in which the rollup was created
|
| 35 |
+
RollupCreationBlockNum uint64 `json:"rollupCreationBlockNumber"`
|
| 36 |
+
// L1: block number in which the rollup manager was created
|
| 37 |
+
RollupManagerCreationBlockNum uint64 `json:"rollupManagerCreationBlockNumber"`
|
| 38 |
// L2: List of states contracts used to populate merkle tree at initial state
|
| 39 |
Genesis []genesisAccountFromJSON `json:"genesis"`
|
| 40 |
// L1: configuration of the network
|
|
|
|
| 59 |
func (cfg *Config) loadNetworkConfig(ctx *cli.Context) {
|
| 60 |
var networkJSON string
|
| 61 |
switch ctx.String(FlagNetwork) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
case string(custom):
|
| 63 |
var err error
|
| 64 |
cfgPath := ctx.String(FlagCustomNetwork)
|
|
|
|
| 67 |
panic(err.Error())
|
| 68 |
}
|
| 69 |
default:
|
| 70 |
+
log.Fatalf("unsupported --network value. Must be %s", custom)
|
| 71 |
}
|
| 72 |
config, err := LoadGenesisFromJSONString(networkJSON)
|
| 73 |
if err != nil {
|
|
|
|
| 115 |
|
| 116 |
cfg.L1Config = cfgJSON.L1Config
|
| 117 |
cfg.Genesis = state.Genesis{
|
| 118 |
+
RollupBlockNumber: cfgJSON.RollupCreationBlockNum,
|
| 119 |
+
RollupManagerBlockNumber: cfgJSON.RollupManagerCreationBlockNum,
|
| 120 |
+
Root: common.HexToHash(cfgJSON.Root),
|
| 121 |
+
Actions: []*state.GenesisAction{},
|
| 122 |
}
|
| 123 |
|
| 124 |
for _, account := range cfgJSON.Genesis {
|
|
@@ -14,18 +13,6 @@
|
|
| 14 |
"github.com/urfave/cli/v2"
|
| 15 |
)
|
| 16 |
|
| 17 |
-
func TestCardona(t *testing.T) {
|
| 18 |
-
cfg := Config{}
|
| 19 |
-
fs := flag.NewFlagSet("", flag.ExitOnError)
|
| 20 |
-
fs.String(FlagNetwork, string(cardona), string(cardona))
|
| 21 |
-
err := fs.Set(FlagNetwork, string(cardona))
|
| 22 |
-
require.NoError(t, err)
|
| 23 |
-
app := cli.NewApp()
|
| 24 |
-
ctx := cli.NewContext(app, fs, nil)
|
| 25 |
-
|
| 26 |
-
log.Info("flag=", ctx.String(FlagNetwork))
|
| 27 |
-
cfg.loadNetworkConfig(ctx)
|
| 28 |
-
}
|
| 29 |
func TestLoadCustomNetworkConfig(t *testing.T) {
|
| 30 |
tcs := []struct {
|
| 31 |
description string
|
|
@@ -37,7 +24,8 @@
|
|
| 37 |
description: "happy path",
|
| 38 |
inputConfigStr: `{
|
| 39 |
"root": "0xBEEF",
|
| 40 |
-
"
|
|
|
|
| 41 |
"l1Config" : {
|
| 42 |
"chainId": 420,
|
| 43 |
"polygonZkEVMAddress": "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
@@ -89,8 +77,9 @@
|
|
| 89 |
GlobalExitRootManagerAddr: common.HexToAddress("0xc949254d682d8c9ad5682521675b8f43b102aec4"),
|
| 90 |
},
|
| 91 |
Genesis: state.Genesis{
|
| 92 |
-
Root:
|
| 93 |
-
|
|
|
|
| 94 |
Actions: []*state.GenesisAction{
|
| 95 |
{
|
| 96 |
Address: "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
|
|
| 13 |
"github.com/urfave/cli/v2"
|
| 14 |
)
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
func TestLoadCustomNetworkConfig(t *testing.T) {
|
| 17 |
tcs := []struct {
|
| 18 |
description string
|
|
|
|
| 24 |
description: "happy path",
|
| 25 |
inputConfigStr: `{
|
| 26 |
"root": "0xBEEF",
|
| 27 |
+
"rollupCreationBlockNumber": 69,
|
| 28 |
+
"rollupManagerCreationBlockNumber": 60,
|
| 29 |
"l1Config" : {
|
| 30 |
"chainId": 420,
|
| 31 |
"polygonZkEVMAddress": "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
|
|
| 77 |
GlobalExitRootManagerAddr: common.HexToAddress("0xc949254d682d8c9ad5682521675b8f43b102aec4"),
|
| 78 |
},
|
| 79 |
Genesis: state.Genesis{
|
| 80 |
+
Root: common.HexToHash("0xBEEF"),
|
| 81 |
+
RollupBlockNumber: 69,
|
| 82 |
+
RollupManagerBlockNumber: 60,
|
| 83 |
Actions: []*state.GenesisAction{
|
| 84 |
{
|
| 85 |
Address: "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
@@ -1,108 +0,0 @@
|
|
| 1 |
-
package config
|
| 2 |
-
|
| 3 |
-
// TestnetNetworkConfigJSON is the hardcoded network configuration to be used for the official mainnet setup
|
| 4 |
-
const TestnetNetworkConfigJSON = `
|
| 5 |
-
{
|
| 6 |
-
"l1Config" : {
|
| 7 |
-
"chainId": 5,
|
| 8 |
-
"polygonZkEVMAddress": "0xa997cfD539E703921fD1e3Cf25b4c241a27a4c7A",
|
| 9 |
-
"polTokenAddress": "0x1319D23c2F7034F52Eb07399702B040bA278Ca49",
|
| 10 |
-
"polygonZkEVMGlobalExitRootAddress": "0x4d9427DCA0406358445bC0a8F88C26b704004f74"
|
| 11 |
-
},
|
| 12 |
-
"root": "0x13a14c4a8288e782863d7ce916d224546c69dc428fbfa7115a0cc33a27a05b26",
|
| 13 |
-
"genesisBlockNumber": 8572998,
|
| 14 |
-
"genesis": [
|
| 15 |
-
{
|
| 16 |
-
"contractName": "PolygonZkEVMDeployer",
|
| 17 |
-
"balance": "0",
|
| 18 |
-
"nonce": "4",
|
| 19 |
-
"address": "0x39877a0c3cd148476DaA2475c77c478C62eC7509",
|
| 20 |
-
"bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212200b8e3cd6bd762444a7eeff86e1cfcd7e1ce9524b715dcb70b2a4c2b70fd5188464736f6c63430008110033",
|
| 21 |
-
"storage": {
|
| 22 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000a0b02b28920812324f1cc3255bd8840867d3f227"
|
| 23 |
-
}
|
| 24 |
-
},
|
| 25 |
-
{
|
| 26 |
-
"contractName": "ProxyAdmin",
|
| 27 |
-
"balance": "0",
|
| 28 |
-
"nonce": "1",
|
| 29 |
-
"address": "0x40797c2f93298a44a893F43EdF1B33B63d7BA333",
|
| 30 |
-
"bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220babd4ff1f5daee002b96cc86d8bb6c2c2c210ae3132df5ea384713352f7f15fe64736f6c63430008110033",
|
| 31 |
-
"storage": {
|
| 32 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000002245d7b6cb0b6870d1e28ac877ee355b9588869"
|
| 33 |
-
}
|
| 34 |
-
},
|
| 35 |
-
{
|
| 36 |
-
"contractName": "PolygonZkEVMBridge implementation",
|
| 37 |
-
"balance": "0",
|
| 38 |
-
"nonce": "1",
|
| 39 |
-
"address": "0x39e780D8800f7396e8B7530A8925B14025AedC77",
|
| 40 |
-
"bytecode": "0x6080604052600436106200019f5760003560e01c8063647c576c11620000e7578063be5831c71162000089578063dbc169761162000060578063dbc169761462000639578063ee25560b1462000651578063fb570834146200068257600080fd5b8063be5831c714620005ae578063cd58657914620005ea578063d02103ca146200060157600080fd5b80639e34070f11620000be5780639e34070f146200050a578063aaa13cc2146200054f578063bab161bf146200057457600080fd5b8063647c576c146200048657806379e2cf9714620004ab57806381b1c17414620004c357600080fd5b80632d2c9d94116200015157806334ac9cf2116200012857806334ac9cf2146200034b5780633ae05047146200037a5780633e197043146200039257600080fd5b80632d2c9d9414620002765780632dfdf0b5146200029b578063318aee3d14620002c257600080fd5b806322e95f2c116200018657806322e95f2c14620001ef578063240ff378146200023a5780632cffd02e146200025157600080fd5b806315064c9614620001a45780632072f6c514620001d5575b600080fd5b348015620001b157600080fd5b50606854620001c09060ff1681565b60405190151581526020015b60405180910390f35b348015620001e257600080fd5b50620001ed620006a7565b005b348015620001fc57600080fd5b50620002146200020e366004620032db565b62000705565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001cc565b620001ed6200024b36600462003372565b620007a8565b3480156200025e57600080fd5b50620001ed6200027036600462003409565b620009d0565b3480156200028357600080fd5b50620001ed6200029536600462003409565b62000f74565b348015620002a857600080fd5b50620002b360535481565b604051908152602001620001cc565b348015620002cf57600080fd5b5062000319620002e1366004620034ef565b606b6020526000908152604090205463ffffffff811690640100000000900473ffffffffffffffffffffffffffffffffffffffff1682565b6040805163ffffffff909316835273ffffffffffffffffffffffffffffffffffffffff909116602083015201620001cc565b3480156200035857600080fd5b50606c54620002149073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200038757600080fd5b50620002b362001178565b3480156200039f57600080fd5b50620002b3620003b136600462003526565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b3480156200049357600080fd5b50620001ed620004a5366004620035b0565b6200125e565b348015620004b857600080fd5b50620001ed620014ad565b348015620004d057600080fd5b5062000214620004e236600462003600565b606a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200051757600080fd5b50620001c06200052936600462003600565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200055c57600080fd5b50620002146200056e3660046200361a565b620014e7565b3480156200058157600080fd5b506068546200059890610100900463ffffffff1681565b60405163ffffffff9091168152602001620001cc565b348015620005bb57600080fd5b506068546200059890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b620001ed620005fb366004620036ce565b620016d3565b3480156200060e57600080fd5b50606854620002149065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200064657600080fd5b50620001ed62001c37565b3480156200065e57600080fd5b50620002b36200067036600462003600565b60696020526000908152604090205481565b3480156200068f57600080fd5b50620001c0620006a136600462003770565b62001c93565b606c5473ffffffffffffffffffffffffffffffffffffffff163314620006f9576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362001d7c565b565b6040805160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016602080830191909152606084901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602483015282516018818403018152603890920183528151918101919091206000908152606a909152205473ffffffffffffffffffffffffffffffffffffffff165b92915050565b60685460ff1615620007e6576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff8681166101009092041614806200080c5750600263ffffffff861610155b1562000844576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff163388883488886053546040516200089a9998979695949392919062003806565b60405180910390a1620009b8620009b26001606860019054906101000a900463ffffffff16338989348989604051620008d592919062003881565b60405180910390206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b62001e10565b8215620009c957620009c962001f27565b5050505050565b60685460ff161562000a0e576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000a258b8b8b8b8b8b8b8b8b8b8b600062001ffc565b73ffffffffffffffffffffffffffffffffffffffff861662000b01576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff861690859060405162000a7a9190620038e6565b60006040518083038185875af1925050503d806000811462000ab9576040519150601f19603f3d011682016040523d82523d6000602084013e62000abe565b606091505b505090508062000afa576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5062000efc565b60685463ffffffff61010090910481169088160362000b435762000b3d73ffffffffffffffffffffffffffffffffffffffff87168585620021ed565b62000efc565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b166024820152600090603801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152606a90935291205490915073ffffffffffffffffffffffffffffffffffffffff168062000e6e576000808062000c1886880188620039fb565b92509250925060008584848460405162000c329062003292565b62000c409392919062003abd565b8190604051809103906000f590508015801562000c61573d6000803e3d6000fd5b506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b15801562000cd757600080fd5b505af115801562000cec573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180604001604052808e63ffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815250606b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000e5c95949392919062003afa565b60405180910390a15050505062000ef9565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000edf57600080fd5b505af115801562000ef4573d6000803e3d6000fd5b505050505b50505b6040805163ffffffff8c811682528916602082015273ffffffffffffffffffffffffffffffffffffffff88811682840152861660608201526080810185905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a15050505050505050505050565b60685460ff161562000fb2576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000fc98b8b8b8b8b8b8b8b8b8b8b600162001ffc565b60008473ffffffffffffffffffffffffffffffffffffffff1684888a868660405160240162000ffc949392919062003b42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1806b5f200000000000000000000000000000000000000000000000000000000179052516200107f9190620038e6565b60006040518083038185875af1925050503d8060008114620010be576040519150601f19603f3d011682016040523d82523d6000602084013e620010c3565b606091505b5050905080620010ff576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805163ffffffff8d811682528a16602082015273ffffffffffffffffffffffffffffffffffffffff89811682840152871660608201526080810186905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a1505050505050505050505050565b605354600090819081805b602081101562001255578083901c600116600103620011e65760338160208110620011b257620011b262003b8a565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062001213565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806200124c9062003be8565b91505062001183565b50919392505050565b600054610100900460ff16158080156200127f5750600054600160ff909116105b806200129b5750303b1580156200129b575060005460ff166001145b6200132d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200138c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8716027fffffffffffffff0000000000000000000000000000000000000000ffffffffff16176501000000000073ffffffffffffffffffffffffffffffffffffffff8681169190910291909117909155606c80547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905562001443620022c3565b8015620014a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854790100000000000000000000000000000000000000000000000000900463ffffffff16101562000703576200070362001f27565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660248201526000908190603801604051602081830303815290604052805190602001209050600060ff60f81b3083604051806020016200157d9062003292565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052620015c8908d908d908d908d908d9060200162003c23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262001606929160200162003c64565b604051602081830303815290604052805190602001206040516020016200168f94939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101209a9950505050505050505050565b60685460ff161562001711576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200171b62002366565b60685463ffffffff888116610100909204161480620017415750600263ffffffff881610155b1562001779576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060608773ffffffffffffffffffffffffffffffffffffffff8816620017df57883414620017d5576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000925062001ad9565b341562001818576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8089166000908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901562001908576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b158015620018db57600080fd5b505af1158015620018f0573d6000803e3d6000fd5b50505050806020015194508060000151935062001ad7565b85156200191d576200191d898b8989620023db565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa1580156200198b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019b1919062003c97565b9050620019d773ffffffffffffffffffffffffffffffffffffffff8b1633308e620028f9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8c16906370a0823190602401602060405180830381865afa15801562001a45573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6b919062003c97565b905062001a79828262003cb1565b6068548c9850610100900463ffffffff169650935062001a998762002959565b62001aa48c62002a71565b62001aaf8d62002b7e565b60405160200162001ac39392919062003abd565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405162001b1b98979695949392919062003cc7565b60405180910390a162001c0f620009b2600085878f8f8789805190602001206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b861562001c205762001c2062001f27565b5050505062001c2e60018055565b50505050505050565b606c5473ffffffffffffffffffffffffffffffffffffffff16331462001c89576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362002c80565b600084815b602081101562001d6e57600163ffffffff8616821c8116900362001d0a5785816020811062001ccb5762001ccb62003b8a565b60200201358260405160200162001cec929190918252602082015260400190565b60405160208183030381529060405280519060200120915062001d59565b8186826020811062001d205762001d2062003b8a565b602002013560405160200162001d40929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b8062001d658162003be8565b91505062001c98565b50821490505b949350505050565b60685460ff161562001dba576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b80600162001e216020600262003e79565b62001e2d919062003cb1565b6053541062001e68576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060536000815462001e7b9062003be8565b9182905550905060005b602081101562001f17578082901c60011660010362001ebd57826033826020811062001eb55762001eb562003b8a565b015550505050565b6033816020811062001ed35762001ed362003b8a565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808062001f0e9062003be8565b91505062001e85565b5062001f2262003e87565b505050565b6053546068805463ffffffff909216790100000000000000000000000000000000000000000000000000027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179081905573ffffffffffffffffffffffffffffffffffffffff65010000000000909104166333d6247d62001fad62001178565b6040518263ffffffff1660e01b815260040162001fcc91815260200190565b600060405180830381600087803b15801562001fe757600080fd5b505af1158015620014a7573d6000803e3d6000fd5b6200200d8b63ffffffff1662002d10565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101207f257b363200000000000000000000000000000000000000000000000000000000909252606481019190915260009165010000000000900473ffffffffffffffffffffffffffffffffffffffff169063257b3632906084016020604051808303816000875af1158015620020b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020d6919062003c97565b90508060000362002112576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff88811661010090920416146200215c576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606854600090610100900463ffffffff166200217a5750896200217d565b508a5b620021a66200219d848c8c8c8c8c8c8c604051620008d592919062003881565b8f8f8462001c93565b620021dd576040517fe0417cec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262001f229084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262002d75565b600054610100900460ff166200235c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6200070362002e88565b600260015403620023d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001324565b6002600155565b6000620023ec600482848662003eb6565b620023f79162003ee2565b90507f2afa5331000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601620026765760008080808080806200245a896004818d62003eb6565b81019062002469919062003f2b565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614620024dd576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861630146200252d576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a851462002567576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff89811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e1691620026229190620038e6565b6000604051808303816000865af19150503d806000811462002661576040519150601f19603f3d011682016040523d82523d6000602084013e62002666565b606091505b50505050505050505050620009c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c0000000000000000000000000000000000000000000000000000000014620026f2576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080808080806200270a8a6004818e62003eb6565b81019062002719919062003f86565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146200278f576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87163014620027df576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c000000000000000000000000000000000000000000000000000000001790529151918f1691620028a39190620038e6565b6000604051808303816000865af19150503d8060008114620028e2576040519150601f19603f3d011682016040523d82523d6000602084013e620028e7565b606091505b50505050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620014a79085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162002240565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620029dd9190620038e6565b600060405180830381855afa9150503d806000811462002a1a576040519150601f19603f3d011682016040523d82523d6000602084013e62002a1f565b606091505b50915091508162002a66576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062001d74565b62001d748162002f21565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff86169162002af59190620038e6565b600060405180830381855afa9150503d806000811462002b32576040519150601f19603f3d011682016040523d82523d6000602084013e62002b37565b606091505b50915091508162002a66576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062001d74565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162002c019190620038e6565b600060405180830381855afa9150503d806000811462002c3e576040519150601f19603f3d011682016040523d82523d6000602084013e62002c43565b606091505b509150915081801562002c57575080516020145b62002c6457601262001d74565b8080602001905181019062001d74919062004012565b60018055565b60685460ff1662002cbd576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620009c9576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062002dd9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620031119092919063ffffffff16565b80519091501562001f22578080602001905181019062002dfa919062004032565b62001f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162001324565b600054610100900460ff1662002c7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6060604082511062002f435781806020019051810190620007a2919062004052565b8151602003620030d35760005b60208110801562002f9b575082818151811062002f715762002f7162003b8a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562002fb6578062002fad8162003be8565b91505062002f50565b8060000362002ffa57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003018576200301862003891565b6040519080825280601f01601f19166020018201604052801562003043576020820181803683370190505b50905060005b82811015620030cb5784818151811062003067576200306762003b8a565b602001015160f81c60f81b82828151811062003087576200308762003b8a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620030c28162003be8565b91505062003049565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b606062001d748484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051620031489190620038e6565b60006040518083038185875af1925050503d806000811462003187576040519150601f19603f3d011682016040523d82523d6000602084013e6200318c565b606091505b50915091506200319f87838387620031aa565b979650505050505050565b60608315620032455782516000036200323d5773ffffffffffffffffffffffffffffffffffffffff85163b6200323d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001324565b508162001d74565b62001d7483838151156200325c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013249190620040d2565b611b6680620040e883390190565b803563ffffffff811681146200310c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114620032d857600080fd5b50565b60008060408385031215620032ef57600080fd5b620032fa83620032a0565b915060208301356200330c81620032b5565b809150509250929050565b8015158114620032d857600080fd5b60008083601f8401126200333957600080fd5b50813567ffffffffffffffff8111156200335257600080fd5b6020830191508360208285010111156200336b57600080fd5b9250929050565b6000806000806000608086880312156200338b57600080fd5b6200339686620032a0565b94506020860135620033a881620032b5565b93506040860135620033ba8162003317565b9250606086013567ffffffffffffffff811115620033d757600080fd5b620033e58882890162003326565b969995985093965092949392505050565b806104008101831015620007a257600080fd5b60008060008060008060008060008060006105208c8e0312156200342c57600080fd5b620034388d8d620033f6565b9a50620034496104008d01620032a0565b99506104208c013598506104408c013597506200346a6104608d01620032a0565b96506104808c01356200347d81620032b5565b95506200348e6104a08d01620032a0565b94506104c08c0135620034a181620032b5565b93506104e08c013592506105008c013567ffffffffffffffff811115620034c757600080fd5b620034d58e828f0162003326565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200350257600080fd5b81356200350f81620032b5565b9392505050565b60ff81168114620032d857600080fd5b600080600080600080600060e0888a0312156200354257600080fd5b87356200354f8162003516565b96506200355f60208901620032a0565b955060408801356200357181620032b5565b94506200358160608901620032a0565b935060808801356200359381620032b5565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215620035c657600080fd5b620035d184620032a0565b92506020840135620035e381620032b5565b91506040840135620035f581620032b5565b809150509250925092565b6000602082840312156200361357600080fd5b5035919050565b600080600080600080600060a0888a0312156200363657600080fd5b6200364188620032a0565b965060208801356200365381620032b5565b9550604088013567ffffffffffffffff808211156200367157600080fd5b6200367f8b838c0162003326565b909750955060608a01359150808211156200369957600080fd5b50620036a88a828b0162003326565b9094509250506080880135620036be8162003516565b8091505092959891949750929550565b600080600080600080600060c0888a031215620036ea57600080fd5b620036f588620032a0565b965060208801356200370781620032b5565b95506040880135945060608801356200372081620032b5565b93506080880135620037328162003317565b925060a088013567ffffffffffffffff8111156200374f57600080fd5b6200375d8a828b0162003326565b989b979a50959850939692959293505050565b60008060008061046085870312156200378857600080fd5b843593506200379b8660208701620033f6565b9250620037ac6104208601620032a0565b939692955092936104400135925050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600061010060ff8c16835263ffffffff808c16602085015273ffffffffffffffffffffffffffffffffffffffff808c166040860152818b166060860152808a166080860152508760a08501528160c0850152620038678285018789620037bd565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b83811015620038dd578181015183820152602001620038c3565b50506000910152565b60008251620038fa818460208701620038c0565b9190910192915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156200394e576200394e62003891565b604052919050565b600067ffffffffffffffff82111562003973576200397362003891565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620039b157600080fd5b8135620039c8620039c28262003956565b62003904565b818152846020838601011115620039de57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562003a1157600080fd5b833567ffffffffffffffff8082111562003a2a57600080fd5b62003a38878388016200399f565b9450602086013591508082111562003a4f57600080fd5b5062003a5e868287016200399f565b9250506040840135620035f58162003516565b6000815180845262003a8b816020860160208601620038c0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600062003ad2606083018662003a71565b828103602084015262003ae6818662003a71565b91505060ff83166040830152949350505050565b63ffffffff86168152600073ffffffffffffffffffffffffffffffffffffffff8087166020840152808616604084015250608060608301526200319f608083018486620037bd565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff8416602082015260606040820152600062003b80606083018486620037bd565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362003c1c5762003c1c62003bb9565b5060010190565b60608152600062003c39606083018789620037bd565b828103602084015262003c4e818688620037bd565b91505060ff831660408301529695505050505050565b6000835162003c78818460208801620038c0565b83519083019062003c8e818360208801620038c0565b01949350505050565b60006020828403121562003caa57600080fd5b5051919050565b81810381811115620007a257620007a262003bb9565b600061010060ff8b16835263ffffffff808b16602085015273ffffffffffffffffffffffffffffffffffffffff808b166040860152818a1660608601528089166080860152508660a08501528160c085015262003d278285018762003a71565b925080851660e085015250509998505050505050505050565b600181815b8085111562003d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003d835762003d8362003bb9565b8085161562003d9157918102915b93841c939080029062003d45565b509250929050565b60008262003db857506001620007a2565b8162003dc757506000620007a2565b816001811462003de0576002811462003deb5762003e0b565b6001915050620007a2565b60ff84111562003dff5762003dff62003bb9565b50506001821b620007a2565b5060208310610133831016604e8410600b841016171562003e30575081810a620007a2565b62003e3c838362003d40565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003e715762003e7162003bb9565b029392505050565b60006200350f838362003da7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000808585111562003ec757600080fd5b8386111562003ed557600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562003f235780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562003f4757600080fd5b873562003f5481620032b5565b9650602088013562003f6681620032b5565b955060408801359450606088013593506080880135620035938162003516565b600080600080600080600080610100898b03121562003fa457600080fd5b883562003fb181620032b5565b9750602089013562003fc381620032b5565b96506040890135955060608901359450608089013562003fe38162003317565b935060a089013562003ff58162003516565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200402557600080fd5b81516200350f8162003516565b6000602082840312156200404557600080fd5b81516200350f8162003317565b6000602082840312156200406557600080fd5b815167ffffffffffffffff8111156200407d57600080fd5b8201601f810184136200408f57600080fd5b8051620040a0620039c28262003956565b818152856020838501011115620040b657600080fd5b620040c9826020830160208601620038c0565b95945050505050565b6020815260006200350f602083018462003a7156fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220addfd62f466d34ee002afbb4ae37b6be56ad421fe773f800badeb4ce1025089864736f6c63430008110033"
|
| 41 |
-
},
|
| 42 |
-
{
|
| 43 |
-
"contractName": "PolygonZkEVMBridge proxy",
|
| 44 |
-
"balance": "200000000000000000000000000",
|
| 45 |
-
"nonce": "1",
|
| 46 |
-
"address": "0xF6BEEeBB578e214CA9E23B0e9683454Ff88Ed2A7",
|
| 47 |
-
"bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461088b565b610135565b61006b6100a33660046108a6565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461088b565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109bb602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161052a565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b61042283610552565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a16101748161059f565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516104cf919061094d565b600060405180830381855af49150503d806000811461050a576040519150601f19603f3d011682016040523d82523d6000602084013e61050f565b606091505b5091509150610520868383876106ab565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b61055b81610753565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8116610642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561074157825160000361073a5773ffffffffffffffffffffffffffffffffffffffff85163b61073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103a2565b508161074b565b61074b838361081e565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6107f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610665565b81511561082e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610969565b803573ffffffffffffffffffffffffffffffffffffffff8116811461088657600080fd5b919050565b60006020828403121561089d57600080fd5b6102b182610862565b6000806000604084860312156108bb57600080fd5b6108c484610862565b9250602084013567ffffffffffffffff808211156108e157600080fd5b818601915086601f8301126108f557600080fd5b81358181111561090457600080fd5b87602082850101111561091657600080fd5b6020830194508093505050509250925092565b60005b8381101561094457818101518382015260200161092c565b50506000910152565b6000825161095f818460208701610929565b9190910192915050565b6020815260008251806020840152610988816040850160208701610929565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1af0d6cb4f1e31496a4c5c1448913bce4bd6ad3a39e47c6f7190c114d6f9bf464736f6c63430008110033",
|
| 48 |
-
"storage": {
|
| 49 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 50 |
-
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 51 |
-
"0x0000000000000000000000000000000000000000000000000000000000000068": "0x00000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa0000000100",
|
| 52 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000040797c2f93298a44a893f43edf1b33b63d7ba333",
|
| 53 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000039e780d8800f7396e8b7530a8925b14025aedc77"
|
| 54 |
-
}
|
| 55 |
-
},
|
| 56 |
-
{
|
| 57 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 implementation",
|
| 58 |
-
"balance": "0",
|
| 59 |
-
"nonce": "1",
|
| 60 |
-
"address": "0x77Fc57b154fCF8320Df2C2e6C044AA50141c023b",
|
| 61 |
-
"bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f000000000000000000000000f6beeebb578e214ca9e23b0e9683454ff88ed2a781565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f6beeebb578e214ca9e23b0e9683454ff88ed2a7161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220a187fc278346c1b61c449ea3641002b6eac2bda3351a122a12c35099f933696864736f6c63430008110033"
|
| 62 |
-
},
|
| 63 |
-
{
|
| 64 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 proxy",
|
| 65 |
-
"balance": "0",
|
| 66 |
-
"nonce": "1",
|
| 67 |
-
"address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa",
|
| 68 |
-
"bytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ca565b610118565b61005b6100933660046106e5565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ca565b61020b565b3480156100f557600080fd5b506100ad610235565b610106610292565b610116610111610331565b61033b565b565b61012061035f565b6001600160a01b0316336001600160a01b031614156101575761015481604051806020016040528060008152506000610392565b50565b6101546100fe565b61016761035f565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610392915050565b505050565b6101c36100fe565b60006101da61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb610331565b905090565b6102086100fe565b90565b61021361035f565b6001600160a01b0316336001600160a01b0316141561015757610154816103f1565b600061023f61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb61035f565b606061028583836040518060600160405280602781526020016107e460279139610445565b9392505050565b3b151590565b61029a61035f565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb610519565b3660008037600080366000845af43d6000803e80801561035a573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b61039b83610541565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103dc5750805b156101c3576103eb8383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61041a61035f565b604080516001600160a01b03928316815291841660208301520160405180910390a1610154816105e9565b6060833b6104a45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610328565b600080856001600160a01b0316856040516104bf9190610794565b600060405180830381855af49150503d80600081146104fa576040519150601f19603f3d011682016040523d82523d6000602084013e6104ff565b606091505b509150915061050f828286610675565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610383565b803b6105a55760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610328565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b03811661064e5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610328565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105c8565b60608315610684575081610285565b8251156106945782518084602001fd5b8160405162461bcd60e51b815260040161032891906107b0565b80356001600160a01b03811681146106c557600080fd5b919050565b6000602082840312156106dc57600080fd5b610285826106ae565b6000806000604084860312156106fa57600080fd5b610703846106ae565b9250602084013567ffffffffffffffff8082111561072057600080fd5b818601915086601f83011261073457600080fd5b81358181111561074357600080fd5b87602082850101111561075557600080fd5b6020830194508093505050509250925092565b60005b8381101561078357818101518382015260200161076b565b838111156103eb5750506000910152565b600082516107a6818460208701610768565b9190910192915050565b60208152600082518060208401526107cf816040850160208701610768565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204675187caf3a43285d9a2c1844a981e977bd52a85ff073e7fc649f73847d70a464736f6c63430008090033",
|
| 69 |
-
"storage": {
|
| 70 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000040797c2f93298a44a893f43edf1b33b63d7ba333",
|
| 71 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000077fc57b154fcf8320df2c2e6c044aa50141c023b"
|
| 72 |
-
}
|
| 73 |
-
},
|
| 74 |
-
{
|
| 75 |
-
"contractName": "PolygonZkEVMTimelock",
|
| 76 |
-
"balance": "0",
|
| 77 |
-
"nonce": "1",
|
| 78 |
-
"address": "0x02245d7B6CB0b6870d1e28AC877EE355b9588869",
|
| 79 |
-
"bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c12565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611c87565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611cc9565b6107df565b3480156102be57600080fd5b506102146102cd366004611d35565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e5a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d35565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d35565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611ec2565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d35565b610927565b3480156103f457600080fd5b506101f2610403366004611ec2565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d35565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d35565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611cc9565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f33565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611ec2565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004611fe5565b610d4f565b3480156105db57600080fd5b506103166105ea36600461210e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d35565b610d94565b34801561064057600080fd5b5061025d61064f366004611d35565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611ec2565b610e8f565b6101f261068f366004611fe5565b610eb4565b3480156106a057600080fd5b506103166106af3660046121b8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611204565b6000610728898989898989610ade565b90506107348184611211565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a60405161077096959493929190612266565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261135e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c81336113f5565b600061086c888888888888610ade565b905061087881856114ad565b610884888888886115ea565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122b1565b60405180910390a36108cd816116ee565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611204565b6109228383611797565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f48282611887565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb96959493929190612266565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611204565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611211565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc36122f1565b9050602002016020810190610cd89190612320565b8d8d86818110610cea57610cea6122f1565b905060200201358c8c87818110610d0357610d036122f1565b9050602002810190610d15919061233b565b8c8b604051610d2996959493929190612266565b60405180910390a3610d3a816123cf565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124b7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611204565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611204565b6109228383611887565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f3181336113f5565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ad565b60005b8981101561114b5760008b8b8381811061108c5761108c6122f1565b90506020020160208101906110a19190612320565b905060008a8a848181106110b7576110b76122f1565b9050602002013590503660008a8a868181106110d5576110d56122f1565b90506020028101906110e7919061233b565b915091506110f7848484846115ea565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122b1565b60405180910390a35050505080611144906123cf565b9050611070565b50611155816116ee565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f2919061257e565b156111fd5750600090565b5060025490565b61120e81336113f5565b50565b61121a82610927565b156112a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112af611161565b81101561133e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61134881426125a0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114338161193e565b61143e83602061195d565b60405160200161144f9291906125d7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612658565b6114b6826108d7565b611542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061155e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116149291906126a9565b60006040518083038185875af1925050503d8060008114611651576040519150601f19603f3d011682016040523d82523d6000602084013e611656565b606091505b50509050806116e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b6116f7816108d7565b611783576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118293390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b6060600061196c8360026126b9565b6119779060026125a0565b67ffffffffffffffff81111561198f5761198f611d4e565b6040519080825280601f01601f1916602001820160405280156119b9576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106119f0576119f06122f1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a5357611a536122f1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611a8f8460026126b9565b611a9a9060016125a0565b90505b6001811115611b37577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611adb57611adb6122f1565b1a60f81b828281518110611af157611af16122f1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b30816126d0565b9050611a9d565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bc457600080fd5b919050565b60008083601f840112611bdb57600080fd5b50813567ffffffffffffffff811115611bf357600080fd5b602083019150836020828501011115611c0b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c2d57600080fd5b611c3688611ba0565b965060208801359550604088013567ffffffffffffffff811115611c5957600080fd5b611c658a828b01611bc9565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611c9957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611ce257600080fd5b611ceb87611ba0565b955060208701359450604087013567ffffffffffffffff811115611d0e57600080fd5b611d1a89828a01611bc9565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d4757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc457611dc4611d4e565b604052919050565b600082601f830112611ddd57600080fd5b813567ffffffffffffffff811115611df757611df7611d4e565b611e2860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d7d565b818152846020838601011115611e3d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611e7057600080fd5b611e7985611ba0565b9350611e8760208601611ba0565b925060408501359150606085013567ffffffffffffffff811115611eaa57600080fd5b611eb687828801611dcc565b91505092959194509250565b60008060408385031215611ed557600080fd5b82359150611ee560208401611ba0565b90509250929050565b60008083601f840112611f0057600080fd5b50813567ffffffffffffffff811115611f1857600080fd5b6020830191508360208260051b8501011115611c0b57600080fd5b600080600080600080600080600060c08a8c031215611f5157600080fd5b893567ffffffffffffffff80821115611f6957600080fd5b611f758d838e01611eee565b909b50995060208c0135915080821115611f8e57600080fd5b611f9a8d838e01611eee565b909950975060408c0135915080821115611fb357600080fd5b50611fc08c828d01611eee565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561200157600080fd5b883567ffffffffffffffff8082111561201957600080fd5b6120258c838d01611eee565b909a50985060208b013591508082111561203e57600080fd5b61204a8c838d01611eee565b909850965060408b013591508082111561206357600080fd5b506120708b828c01611eee565b999c989b509699959896976060870135966080013595509350505050565b600082601f83011261209f57600080fd5b8135602067ffffffffffffffff8211156120bb576120bb611d4e565b8160051b6120ca828201611d7d565b92835284810182019282810190878511156120e457600080fd5b83870192505b84831015612103578235825291830191908301906120ea565b979650505050505050565b600080600080600060a0868803121561212657600080fd5b61212f86611ba0565b945061213d60208701611ba0565b9350604086013567ffffffffffffffff8082111561215a57600080fd5b61216689838a0161208e565b9450606088013591508082111561217c57600080fd5b61218889838a0161208e565b9350608088013591508082111561219e57600080fd5b506121ab88828901611dcc565b9150509295509295909350565b600080600080600060a086880312156121d057600080fd5b6121d986611ba0565b94506121e760208701611ba0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561221157600080fd5b6121ab88828901611dcc565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a06040820152600061229c60a08301868861221d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006122e760608301848661221d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561233257600080fd5b6108f682611ba0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261237057600080fd5b83018035915067ffffffffffffffff82111561238b57600080fd5b602001915036819003821315611c0b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612400576124006123a0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124aa57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301811261246057600080fd5b8701858101903567ffffffffffffffff81111561247c57600080fd5b80360382131561248b57600080fd5b61249686828461221d565b9a87019a9550505090840190600101612421565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125055773ffffffffffffffffffffffffffffffffffffffff6124f084611ba0565b168252602092830192909101906001016124ca565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561253e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125669082018789612407565b60608401959095525050608001529695505050505050565b60006020828403121561259057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123a0565b60005b838110156125ce5781810151838201526020016125b6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161260f8160178501602088016125b3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161264c8160288401602088016125b3565b01602801949350505050565b60208152600082518060208401526126778160408501602087016125b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123a0565b6000816126df576126df6123a0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220288c3dd40a2ba96edf066502722584177809ebdb47c0cf9ee8df6f07954c373064736f6c63430008110033",
|
| 80 |
-
"storage": {
|
| 81 |
-
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000015180",
|
| 82 |
-
"0xbdd73c6ebfb442c137537be0985acf11af8e6133078bc51ef9094071cb0ca475": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 83 |
-
"0x92b79801e6a3d148a516c908cc0bbad93771fa74468b7757a14aa55532d092de": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 84 |
-
"0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 85 |
-
"0x43e090632490f7d46c400129311fff008a7688bb3d4aebdf80607456b452cf04": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 86 |
-
"0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 87 |
-
"0x5af21cf0316499c6925cf9be0331b8bd150a1fa4c19d24a043b45f0cf15357c3": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 88 |
-
"0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 89 |
-
"0xaf021eeb38644155cd697b3ce0ec4fdac818d29c448a9f9d9bafc293723c6cd8": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 90 |
-
"0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5"
|
| 91 |
-
}
|
| 92 |
-
},
|
| 93 |
-
{
|
| 94 |
-
"accountName": "keyless Deployer",
|
| 95 |
-
"balance": "0",
|
| 96 |
-
"nonce": "1",
|
| 97 |
-
"address": "0xB83a574B3966F7dc1d38d162FA154F2A57D608Bb"
|
| 98 |
-
},
|
| 99 |
-
{
|
| 100 |
-
"accountName": "deployer",
|
| 101 |
-
"balance": "0",
|
| 102 |
-
"nonce": "8",
|
| 103 |
-
"address": "0xA0B02B28920812324f1cC3255bd8840867d3f227"
|
| 104 |
-
}
|
| 105 |
-
]
|
| 106 |
-
}
|
| 107 |
-
|
| 108 |
-
`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -38,3 +38,13 @@
|
|
| 38 |
},
|
| 39 |
}
|
| 40 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
},
|
| 39 |
}
|
| 40 |
}
|
| 41 |
+
|
| 42 |
+
// MarshalJSON marshalls time duration into text.
|
| 43 |
+
func (d Duration) MarshalJSON() ([]byte, error) {
|
| 44 |
+
return []byte(`"` + d.String() + `"`), nil
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
// MarshalText marshalls time duration into text.
|
| 48 |
+
func (d *Duration) MarshalText() ([]byte, error) {
|
| 49 |
+
return []byte(d.String()), nil
|
| 50 |
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package dataavailability
|
| 2 |
+
|
| 3 |
+
// DABackendType is the data availability protocol for the CDK
|
| 4 |
+
type DABackendType string
|
| 5 |
+
|
| 6 |
+
const (
|
| 7 |
+
// DataAvailabilityCommittee is the DAC protocol backend
|
| 8 |
+
DataAvailabilityCommittee DABackendType = "DataAvailabilityCommittee"
|
| 9 |
+
)
|
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package dataavailability
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"fmt"
|
| 6 |
+
"math/big"
|
| 7 |
+
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/types"
|
| 9 |
+
jsontypes "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
+
"github.com/ethereum/go-ethereum/common"
|
| 12 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
const (
|
| 16 |
+
unexpectedHashTemplate = "mismatch on transaction data for batch num %d. Expected hash %s, actual hash: %s"
|
| 17 |
+
failedDataRetrievalTemplate = "failed to retrieve local data for batches %v: %s"
|
| 18 |
+
invalidBatchRetrievalArgs = "invalid L2 batch data retrieval arguments, %d != %d"
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
// DataAvailability implements an abstract data availability integration
|
| 22 |
+
type DataAvailability struct {
|
| 23 |
+
isTrustedSequencer bool
|
| 24 |
+
|
| 25 |
+
state stateInterface
|
| 26 |
+
zkEVMClient ZKEVMClientTrustedBatchesGetter
|
| 27 |
+
backend DABackender
|
| 28 |
+
|
| 29 |
+
ctx context.Context
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
// New creates a DataAvailability instance
|
| 33 |
+
func New(
|
| 34 |
+
isTrustedSequencer bool,
|
| 35 |
+
backend DABackender,
|
| 36 |
+
state stateInterface,
|
| 37 |
+
zkEVMClient ZKEVMClientTrustedBatchesGetter,
|
| 38 |
+
) (*DataAvailability, error) {
|
| 39 |
+
da := &DataAvailability{
|
| 40 |
+
isTrustedSequencer: isTrustedSequencer,
|
| 41 |
+
backend: backend,
|
| 42 |
+
state: state,
|
| 43 |
+
zkEVMClient: zkEVMClient,
|
| 44 |
+
ctx: context.Background(),
|
| 45 |
+
}
|
| 46 |
+
err := da.backend.Init()
|
| 47 |
+
return da, err
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
// PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage
|
| 51 |
+
// as expected by the contract
|
| 52 |
+
func (d *DataAvailability) PostSequence(ctx context.Context, sequences []types.Sequence) ([]byte, error) {
|
| 53 |
+
batchesData := [][]byte{}
|
| 54 |
+
for _, batch := range sequences {
|
| 55 |
+
// Do not send to the DA backend data that will be stored to L1
|
| 56 |
+
if batch.ForcedBatchTimestamp == 0 {
|
| 57 |
+
batchesData = append(batchesData, batch.BatchL2Data)
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
return d.backend.PostSequence(ctx, batchesData)
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// GetBatchL2Data tries to return the data from a batch, in the following priorities. batchNums should not include forced batches.
|
| 64 |
+
// 1. From local DB
|
| 65 |
+
// 2. From Trusted Sequencer (if not self)
|
| 66 |
+
// 3. From DA backend
|
| 67 |
+
func (d *DataAvailability) GetBatchL2Data(batchNums []uint64, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) {
|
| 68 |
+
if len(batchNums) != len(batchHashes) {
|
| 69 |
+
return nil, fmt.Errorf(invalidBatchRetrievalArgs, len(batchNums), len(batchHashes))
|
| 70 |
+
}
|
| 71 |
+
localData, err := d.state.GetBatchL2DataByNumbers(d.ctx, batchNums, nil)
|
| 72 |
+
if err != nil {
|
| 73 |
+
return nil, err
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
data, err := checkBatches(batchNums, batchHashes, localData)
|
| 77 |
+
if err != nil {
|
| 78 |
+
log.Warnf(failedDataRetrievalTemplate, batchNums, err.Error())
|
| 79 |
+
} else {
|
| 80 |
+
return data, nil
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
if !d.isTrustedSequencer {
|
| 84 |
+
data, err = d.rpcData(batchNums, batchHashes, d.zkEVMClient.BatchesByNumbers)
|
| 85 |
+
if err != nil {
|
| 86 |
+
log.Warnf(failedDataRetrievalTemplate, batchNums, err.Error())
|
| 87 |
+
} else {
|
| 88 |
+
return data, nil
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
return d.backend.GetSequence(d.ctx, batchHashes, dataAvailabilityMessage)
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
func checkBatches(batchNumbers []uint64, expectedHashes []common.Hash, batchData map[uint64][]byte) ([][]byte, error) {
|
| 95 |
+
if len(batchNumbers) != len(expectedHashes) {
|
| 96 |
+
return nil, fmt.Errorf("invalid batch parameters")
|
| 97 |
+
}
|
| 98 |
+
result := make([][]byte, len(batchNumbers))
|
| 99 |
+
for i := 0; i < len(batchNumbers); i++ {
|
| 100 |
+
batchNumber := batchNumbers[i]
|
| 101 |
+
expectedHash := expectedHashes[i]
|
| 102 |
+
bd, ok := batchData[batchNumber]
|
| 103 |
+
if !ok {
|
| 104 |
+
return nil, fmt.Errorf("missing batch data: [%d] %s", batchNumber, expectedHash.Hex())
|
| 105 |
+
}
|
| 106 |
+
actualHash := crypto.Keccak256Hash(bd)
|
| 107 |
+
if actualHash != expectedHash {
|
| 108 |
+
err := fmt.Errorf(unexpectedHashTemplate, batchNumber, expectedHash, actualHash)
|
| 109 |
+
log.Warnf("wrong local data for hash: %s", err.Error())
|
| 110 |
+
return nil, err
|
| 111 |
+
}
|
| 112 |
+
result[i] = bd
|
| 113 |
+
}
|
| 114 |
+
return result, nil
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
type rpcBatchDataFunc func(ctx context.Context, numbers []*big.Int) ([]*jsontypes.BatchData, error)
|
| 118 |
+
|
| 119 |
+
// rpcData retrieves batch data from rpcBatchDataFunc, returns an error unless all are found and correct
|
| 120 |
+
func (d *DataAvailability) rpcData(batchNums []uint64, expectedHashes []common.Hash, rpcFunc rpcBatchDataFunc) ([][]byte, error) {
|
| 121 |
+
if len(batchNums) != len(expectedHashes) {
|
| 122 |
+
return nil, fmt.Errorf("invalid arguments, len of batch numbers does not equal length of expected hashes: %d != %d",
|
| 123 |
+
len(batchNums), len(expectedHashes))
|
| 124 |
+
}
|
| 125 |
+
nums := make([]*big.Int, 0, len(batchNums))
|
| 126 |
+
for _, n := range batchNums {
|
| 127 |
+
nums = append(nums, new(big.Int).SetUint64(n))
|
| 128 |
+
}
|
| 129 |
+
batchData, err := rpcFunc(d.ctx, nums)
|
| 130 |
+
if err != nil {
|
| 131 |
+
return nil, err
|
| 132 |
+
}
|
| 133 |
+
if len(batchData) != len(batchNums) {
|
| 134 |
+
return nil, fmt.Errorf("missing batch data, expected %d, got %d", len(batchNums), len(batchData))
|
| 135 |
+
}
|
| 136 |
+
result := make(map[uint64][]byte)
|
| 137 |
+
for i := 0; i < len(batchNums); i++ {
|
| 138 |
+
number := batchNums[i]
|
| 139 |
+
batch := batchData[i]
|
| 140 |
+
expectedTransactionsHash := expectedHashes[i]
|
| 141 |
+
actualTransactionsHash := crypto.Keccak256Hash(batch.BatchL2Data)
|
| 142 |
+
if expectedTransactionsHash != actualTransactionsHash {
|
| 143 |
+
return nil, fmt.Errorf(unexpectedHashTemplate, number, expectedTransactionsHash, actualTransactionsHash)
|
| 144 |
+
}
|
| 145 |
+
result[number] = batch.BatchL2Data
|
| 146 |
+
}
|
| 147 |
+
checked, err := checkBatches(batchNums, expectedHashes, result)
|
| 148 |
+
if err != nil {
|
| 149 |
+
return nil, err
|
| 150 |
+
}
|
| 151 |
+
return checked, nil
|
| 152 |
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package datacommittee
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"crypto/ecdsa"
|
| 5 |
+
"errors"
|
| 6 |
+
"fmt"
|
| 7 |
+
"math/big"
|
| 8 |
+
"math/rand"
|
| 9 |
+
"sort"
|
| 10 |
+
"strings"
|
| 11 |
+
|
| 12 |
+
"github.com/0xPolygon/cdk-data-availability/client"
|
| 13 |
+
daTypes "github.com/0xPolygon/cdk-data-availability/types"
|
| 14 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee"
|
| 15 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 16 |
+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 17 |
+
"github.com/ethereum/go-ethereum/common"
|
| 18 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 19 |
+
"github.com/ethereum/go-ethereum/ethclient"
|
| 20 |
+
"golang.org/x/net/context"
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
const unexpectedHashTemplate = "missmatch on transaction data. Expected hash %s, actual hash: %s"
|
| 24 |
+
|
| 25 |
+
// DataCommitteeMember represents a member of the Data Committee
|
| 26 |
+
type DataCommitteeMember struct {
|
| 27 |
+
Addr common.Address
|
| 28 |
+
URL string
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
// DataCommittee represents a specific committee
|
| 32 |
+
type DataCommittee struct {
|
| 33 |
+
AddressesHash common.Hash
|
| 34 |
+
Members []DataCommitteeMember
|
| 35 |
+
RequiredSignatures uint64
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// DataCommitteeBackend implements the DAC integration
|
| 39 |
+
type DataCommitteeBackend struct {
|
| 40 |
+
dataCommitteeContract *polygondatacommittee.Polygondatacommittee
|
| 41 |
+
privKey *ecdsa.PrivateKey
|
| 42 |
+
dataCommitteeClientFactory client.Factory
|
| 43 |
+
|
| 44 |
+
committeeMembers []DataCommitteeMember
|
| 45 |
+
selectedCommitteeMember int
|
| 46 |
+
ctx context.Context
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// New creates an instance of DataCommitteeBackend
|
| 50 |
+
func New(
|
| 51 |
+
l1RPCURL string,
|
| 52 |
+
dataCommitteeAddr common.Address,
|
| 53 |
+
privKey *ecdsa.PrivateKey,
|
| 54 |
+
dataCommitteeClientFactory client.Factory,
|
| 55 |
+
) (*DataCommitteeBackend, error) {
|
| 56 |
+
ethClient, err := ethclient.Dial(l1RPCURL)
|
| 57 |
+
if err != nil {
|
| 58 |
+
log.Errorf("error connecting to %s: %+v", l1RPCURL, err)
|
| 59 |
+
return nil, err
|
| 60 |
+
}
|
| 61 |
+
dataCommittee, err := polygondatacommittee.NewPolygondatacommittee(dataCommitteeAddr, ethClient)
|
| 62 |
+
if err != nil {
|
| 63 |
+
return nil, err
|
| 64 |
+
}
|
| 65 |
+
return &DataCommitteeBackend{
|
| 66 |
+
dataCommitteeContract: dataCommittee,
|
| 67 |
+
privKey: privKey,
|
| 68 |
+
dataCommitteeClientFactory: dataCommitteeClientFactory,
|
| 69 |
+
ctx: context.Background(),
|
| 70 |
+
}, nil
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
// Init loads the DAC to be cached when needed
|
| 74 |
+
func (d *DataCommitteeBackend) Init() error {
|
| 75 |
+
committee, err := d.getCurrentDataCommittee()
|
| 76 |
+
if err != nil {
|
| 77 |
+
return err
|
| 78 |
+
}
|
| 79 |
+
selectedCommitteeMember := -1
|
| 80 |
+
if committee != nil {
|
| 81 |
+
d.committeeMembers = committee.Members
|
| 82 |
+
if len(committee.Members) > 0 {
|
| 83 |
+
selectedCommitteeMember = rand.Intn(len(committee.Members)) //nolint:gosec
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
d.selectedCommitteeMember = selectedCommitteeMember
|
| 87 |
+
return nil
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
// GetSequence gets backend data one hash at a time. This should be optimized on the DAC side to get them all at once.
|
| 91 |
+
func (d *DataCommitteeBackend) GetSequence(ctx context.Context, hashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) {
|
| 92 |
+
// TODO: optimize this on the DAC side by implementing a multi batch retrieve api
|
| 93 |
+
var batchData [][]byte
|
| 94 |
+
for _, h := range hashes {
|
| 95 |
+
data, err := d.GetBatchL2Data(h)
|
| 96 |
+
if err != nil {
|
| 97 |
+
return nil, err
|
| 98 |
+
}
|
| 99 |
+
batchData = append(batchData, data)
|
| 100 |
+
}
|
| 101 |
+
return batchData, nil
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
// GetBatchL2Data returns the data from the DAC. It checks that it matches with the expected hash
|
| 105 |
+
func (d *DataCommitteeBackend) GetBatchL2Data(hash common.Hash) ([]byte, error) {
|
| 106 |
+
intialMember := d.selectedCommitteeMember
|
| 107 |
+
found := false
|
| 108 |
+
for !found && intialMember != -1 {
|
| 109 |
+
member := d.committeeMembers[d.selectedCommitteeMember]
|
| 110 |
+
log.Infof("trying to get data from %s at %s", member.Addr.Hex(), member.URL)
|
| 111 |
+
c := d.dataCommitteeClientFactory.New(member.URL)
|
| 112 |
+
data, err := c.GetOffChainData(d.ctx, hash)
|
| 113 |
+
if err != nil {
|
| 114 |
+
log.Warnf(
|
| 115 |
+
"error getting data from DAC node %s at %s: %s",
|
| 116 |
+
member.Addr.Hex(), member.URL, err,
|
| 117 |
+
)
|
| 118 |
+
d.selectedCommitteeMember = (d.selectedCommitteeMember + 1) % len(d.committeeMembers)
|
| 119 |
+
if d.selectedCommitteeMember == intialMember {
|
| 120 |
+
break
|
| 121 |
+
}
|
| 122 |
+
continue
|
| 123 |
+
}
|
| 124 |
+
actualTransactionsHash := crypto.Keccak256Hash(data)
|
| 125 |
+
if actualTransactionsHash != hash {
|
| 126 |
+
unexpectedHash := fmt.Errorf(
|
| 127 |
+
unexpectedHashTemplate, hash, actualTransactionsHash,
|
| 128 |
+
)
|
| 129 |
+
log.Warnf(
|
| 130 |
+
"error getting data from DAC node %s at %s: %s",
|
| 131 |
+
member.Addr.Hex(), member.URL, unexpectedHash,
|
| 132 |
+
)
|
| 133 |
+
d.selectedCommitteeMember = (d.selectedCommitteeMember + 1) % len(d.committeeMembers)
|
| 134 |
+
if d.selectedCommitteeMember == intialMember {
|
| 135 |
+
break
|
| 136 |
+
}
|
| 137 |
+
continue
|
| 138 |
+
}
|
| 139 |
+
return data, nil
|
| 140 |
+
}
|
| 141 |
+
if err := d.Init(); err != nil {
|
| 142 |
+
return nil, fmt.Errorf("error loading data committee: %s", err)
|
| 143 |
+
}
|
| 144 |
+
return nil, fmt.Errorf("couldn't get the data from any committee member")
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
type signatureMsg struct {
|
| 148 |
+
addr common.Address
|
| 149 |
+
signature []byte
|
| 150 |
+
err error
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
// PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage
|
| 154 |
+
// as expected by the contract
|
| 155 |
+
func (s *DataCommitteeBackend) PostSequence(ctx context.Context, batchesData [][]byte) ([]byte, error) {
|
| 156 |
+
// Get current committee
|
| 157 |
+
committee, err := s.getCurrentDataCommittee()
|
| 158 |
+
if err != nil {
|
| 159 |
+
return nil, err
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
// Authenticate as trusted sequencer by signing the sequences
|
| 163 |
+
sequence := daTypes.Sequence{}
|
| 164 |
+
for _, seq := range batchesData {
|
| 165 |
+
sequence = append(sequence, seq)
|
| 166 |
+
}
|
| 167 |
+
signedSequence, err := sequence.Sign(s.privKey)
|
| 168 |
+
if err != nil {
|
| 169 |
+
return nil, err
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
// Request signatures to all members in parallel
|
| 173 |
+
ch := make(chan signatureMsg, len(committee.Members))
|
| 174 |
+
signatureCtx, cancelSignatureCollection := context.WithCancel(ctx)
|
| 175 |
+
for _, member := range committee.Members {
|
| 176 |
+
go requestSignatureFromMember(signatureCtx, *signedSequence, member, ch)
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
// Collect signatures
|
| 180 |
+
msgs := []signatureMsg{}
|
| 181 |
+
var (
|
| 182 |
+
collectedSignatures uint64
|
| 183 |
+
failedToCollect uint64
|
| 184 |
+
)
|
| 185 |
+
for collectedSignatures < committee.RequiredSignatures {
|
| 186 |
+
msg := <-ch
|
| 187 |
+
if msg.err != nil {
|
| 188 |
+
log.Errorf("error when trying to get signature from %s: %s", msg.addr, msg.err)
|
| 189 |
+
failedToCollect++
|
| 190 |
+
if len(committee.Members)-int(failedToCollect) < int(committee.RequiredSignatures) {
|
| 191 |
+
cancelSignatureCollection()
|
| 192 |
+
return nil, errors.New("too many members failed to send their signature")
|
| 193 |
+
}
|
| 194 |
+
} else {
|
| 195 |
+
log.Infof("received signature from %s", msg.addr)
|
| 196 |
+
collectedSignatures++
|
| 197 |
+
}
|
| 198 |
+
msgs = append(msgs, msg)
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
// Stop requesting as soon as we have N valid signatures
|
| 202 |
+
cancelSignatureCollection()
|
| 203 |
+
|
| 204 |
+
return buildSignaturesAndAddrs(signatureMsgs(msgs), committee.Members), nil
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
func requestSignatureFromMember(ctx context.Context, signedSequence daTypes.SignedSequence, member DataCommitteeMember, ch chan signatureMsg) {
|
| 208 |
+
// request
|
| 209 |
+
c := client.New(member.URL)
|
| 210 |
+
log.Infof("sending request to sign the sequence to %s at %s", member.Addr.Hex(), member.URL)
|
| 211 |
+
signature, err := c.SignSequence(signedSequence)
|
| 212 |
+
if err != nil {
|
| 213 |
+
ch <- signatureMsg{
|
| 214 |
+
addr: member.Addr,
|
| 215 |
+
err: err,
|
| 216 |
+
}
|
| 217 |
+
return
|
| 218 |
+
}
|
| 219 |
+
// verify returned signature
|
| 220 |
+
signedSequence.Signature = signature
|
| 221 |
+
signer, err := signedSequence.Signer()
|
| 222 |
+
if err != nil {
|
| 223 |
+
ch <- signatureMsg{
|
| 224 |
+
addr: member.Addr,
|
| 225 |
+
err: err,
|
| 226 |
+
}
|
| 227 |
+
return
|
| 228 |
+
}
|
| 229 |
+
if signer != member.Addr {
|
| 230 |
+
ch <- signatureMsg{
|
| 231 |
+
addr: member.Addr,
|
| 232 |
+
err: fmt.Errorf("invalid signer. Expected %s, actual %s", member.Addr.Hex(), signer.Hex()),
|
| 233 |
+
}
|
| 234 |
+
return
|
| 235 |
+
}
|
| 236 |
+
ch <- signatureMsg{
|
| 237 |
+
addr: member.Addr,
|
| 238 |
+
signature: signature,
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
func buildSignaturesAndAddrs(sigs signatureMsgs, members []DataCommitteeMember) []byte {
|
| 243 |
+
const (
|
| 244 |
+
sigLen = 65
|
| 245 |
+
addrLen = 20
|
| 246 |
+
)
|
| 247 |
+
res := make([]byte, 0, len(sigs)*sigLen+len(members)*addrLen)
|
| 248 |
+
sort.Sort(sigs)
|
| 249 |
+
for _, msg := range sigs {
|
| 250 |
+
log.Debugf("adding signature %s from %s", common.Bytes2Hex(msg.signature), msg.addr.Hex())
|
| 251 |
+
res = append(res, msg.signature...)
|
| 252 |
+
}
|
| 253 |
+
for _, member := range members {
|
| 254 |
+
log.Debugf("adding addr %s", common.Bytes2Hex(member.Addr.Bytes()))
|
| 255 |
+
res = append(res, member.Addr.Bytes()...)
|
| 256 |
+
}
|
| 257 |
+
log.Debugf("full res %s", common.Bytes2Hex(res))
|
| 258 |
+
return res
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
type signatureMsgs []signatureMsg
|
| 262 |
+
|
| 263 |
+
func (s signatureMsgs) Len() int { return len(s) }
|
| 264 |
+
func (s signatureMsgs) Less(i, j int) bool {
|
| 265 |
+
return strings.ToUpper(s[i].addr.Hex()) < strings.ToUpper(s[j].addr.Hex())
|
| 266 |
+
}
|
| 267 |
+
func (s signatureMsgs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
| 268 |
+
|
| 269 |
+
// getCurrentDataCommittee return the currently registered data committee
|
| 270 |
+
func (d *DataCommitteeBackend) getCurrentDataCommittee() (*DataCommittee, error) {
|
| 271 |
+
addrsHash, err := d.dataCommitteeContract.CommitteeHash(&bind.CallOpts{Pending: false})
|
| 272 |
+
if err != nil {
|
| 273 |
+
return nil, fmt.Errorf("error getting CommitteeHash from L1 SC: %w", err)
|
| 274 |
+
}
|
| 275 |
+
reqSign, err := d.dataCommitteeContract.RequiredAmountOfSignatures(&bind.CallOpts{Pending: false})
|
| 276 |
+
if err != nil {
|
| 277 |
+
return nil, fmt.Errorf("error getting RequiredAmountOfSignatures from L1 SC: %w", err)
|
| 278 |
+
}
|
| 279 |
+
members, err := d.getCurrentDataCommitteeMembers()
|
| 280 |
+
if err != nil {
|
| 281 |
+
return nil, err
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
return &DataCommittee{
|
| 285 |
+
AddressesHash: common.Hash(addrsHash),
|
| 286 |
+
RequiredSignatures: reqSign.Uint64(),
|
| 287 |
+
Members: members,
|
| 288 |
+
}, nil
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
// getCurrentDataCommitteeMembers return the currently registered data committee members
|
| 292 |
+
func (d *DataCommitteeBackend) getCurrentDataCommitteeMembers() ([]DataCommitteeMember, error) {
|
| 293 |
+
nMembers, err := d.dataCommitteeContract.GetAmountOfMembers(&bind.CallOpts{Pending: false})
|
| 294 |
+
if err != nil {
|
| 295 |
+
return nil, fmt.Errorf("error getting GetAmountOfMembers from L1 SC: %w", err)
|
| 296 |
+
}
|
| 297 |
+
members := make([]DataCommitteeMember, 0, nMembers.Int64())
|
| 298 |
+
for i := int64(0); i < nMembers.Int64(); i++ {
|
| 299 |
+
member, err := d.dataCommitteeContract.Members(&bind.CallOpts{Pending: false}, big.NewInt(i))
|
| 300 |
+
if err != nil {
|
| 301 |
+
return nil, fmt.Errorf("error getting Members %d from L1 SC: %w", i, err)
|
| 302 |
+
}
|
| 303 |
+
members = append(members, DataCommitteeMember{
|
| 304 |
+
Addr: member.Addr,
|
| 305 |
+
URL: member.Url,
|
| 306 |
+
})
|
| 307 |
+
}
|
| 308 |
+
return members, nil
|
| 309 |
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package datacommittee
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"math/big"
|
| 5 |
+
"testing"
|
| 6 |
+
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee"
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 10 |
+
"github.com/ethereum/go-ethereum/common"
|
| 11 |
+
"github.com/ethereum/go-ethereum/core"
|
| 12 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 13 |
+
"github.com/ethereum/go-ethereum/ethclient/simulated"
|
| 14 |
+
"github.com/stretchr/testify/assert"
|
| 15 |
+
"github.com/stretchr/testify/require"
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
func TestUpdateDataCommitteeEvent(t *testing.T) {
|
| 19 |
+
// Set up testing environment
|
| 20 |
+
dac, ethBackend, auth, da := newTestingEnv(t)
|
| 21 |
+
|
| 22 |
+
// Update the committee
|
| 23 |
+
requiredAmountOfSignatures := big.NewInt(2)
|
| 24 |
+
URLs := []string{"1", "2", "3"}
|
| 25 |
+
addrs := []common.Address{
|
| 26 |
+
common.HexToAddress("0x1"),
|
| 27 |
+
common.HexToAddress("0x2"),
|
| 28 |
+
common.HexToAddress("0x3"),
|
| 29 |
+
}
|
| 30 |
+
addrsBytes := []byte{}
|
| 31 |
+
for _, addr := range addrs {
|
| 32 |
+
addrsBytes = append(addrsBytes, addr.Bytes()...)
|
| 33 |
+
}
|
| 34 |
+
_, err := da.SetupCommittee(auth, requiredAmountOfSignatures, URLs, addrsBytes)
|
| 35 |
+
require.NoError(t, err)
|
| 36 |
+
ethBackend.Commit()
|
| 37 |
+
|
| 38 |
+
// Assert the committee update
|
| 39 |
+
actualSetup, err := dac.getCurrentDataCommittee()
|
| 40 |
+
require.NoError(t, err)
|
| 41 |
+
expectedMembers := []DataCommitteeMember{}
|
| 42 |
+
expectedSetup := DataCommittee{
|
| 43 |
+
RequiredSignatures: uint64(len(URLs) - 1),
|
| 44 |
+
AddressesHash: crypto.Keccak256Hash(addrsBytes),
|
| 45 |
+
}
|
| 46 |
+
for i, url := range URLs {
|
| 47 |
+
expectedMembers = append(expectedMembers, DataCommitteeMember{
|
| 48 |
+
URL: url,
|
| 49 |
+
Addr: addrs[i],
|
| 50 |
+
})
|
| 51 |
+
}
|
| 52 |
+
expectedSetup.Members = expectedMembers
|
| 53 |
+
assert.Equal(t, expectedSetup, *actualSetup)
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
func init() {
|
| 57 |
+
log.Init(log.Config{
|
| 58 |
+
Level: "debug",
|
| 59 |
+
Outputs: []string{"stderr"},
|
| 60 |
+
})
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// This function prepare the blockchain, the wallet with funds and deploy the smc
|
| 64 |
+
func newTestingEnv(t *testing.T) (
|
| 65 |
+
dac *DataCommitteeBackend,
|
| 66 |
+
ethBackend *simulated.Backend,
|
| 67 |
+
auth *bind.TransactOpts,
|
| 68 |
+
da *polygondatacommittee.Polygondatacommittee,
|
| 69 |
+
) {
|
| 70 |
+
t.Helper()
|
| 71 |
+
privateKey, err := crypto.GenerateKey()
|
| 72 |
+
if err != nil {
|
| 73 |
+
log.Fatal(err)
|
| 74 |
+
}
|
| 75 |
+
auth, err = bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337))
|
| 76 |
+
if err != nil {
|
| 77 |
+
log.Fatal(err)
|
| 78 |
+
}
|
| 79 |
+
dac, ethBackend, da, err = newSimulatedDacman(t, auth)
|
| 80 |
+
if err != nil {
|
| 81 |
+
log.Fatal(err)
|
| 82 |
+
}
|
| 83 |
+
return dac, ethBackend, auth, da
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
// NewSimulatedEtherman creates an etherman that uses a simulated blockchain. It's important to notice that the ChainID of the auth
|
| 87 |
+
// must be 1337. The address that holds the auth will have an initial balance of 10 ETH
|
| 88 |
+
func newSimulatedDacman(t *testing.T, auth *bind.TransactOpts) (
|
| 89 |
+
dacman *DataCommitteeBackend,
|
| 90 |
+
ethBackend *simulated.Backend,
|
| 91 |
+
da *polygondatacommittee.Polygondatacommittee,
|
| 92 |
+
err error,
|
| 93 |
+
) {
|
| 94 |
+
t.Helper()
|
| 95 |
+
if auth == nil {
|
| 96 |
+
// read only client
|
| 97 |
+
return &DataCommitteeBackend{}, nil, nil, nil
|
| 98 |
+
}
|
| 99 |
+
// 10000000 ETH in wei
|
| 100 |
+
balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd
|
| 101 |
+
address := auth.From
|
| 102 |
+
genesisAlloc := map[common.Address]core.GenesisAccount{
|
| 103 |
+
address: {
|
| 104 |
+
Balance: balance,
|
| 105 |
+
},
|
| 106 |
+
}
|
| 107 |
+
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
|
| 108 |
+
client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 109 |
+
|
| 110 |
+
// DAC Setup
|
| 111 |
+
_, _, da, err = polygondatacommittee.DeployPolygondatacommittee(auth, client.Client())
|
| 112 |
+
if err != nil {
|
| 113 |
+
return &DataCommitteeBackend{}, nil, nil, err
|
| 114 |
+
}
|
| 115 |
+
client.Commit()
|
| 116 |
+
_, err = da.Initialize(auth)
|
| 117 |
+
if err != nil {
|
| 118 |
+
return &DataCommitteeBackend{}, nil, nil, err
|
| 119 |
+
}
|
| 120 |
+
client.Commit()
|
| 121 |
+
_, err = da.SetupCommittee(auth, big.NewInt(0), []string{}, []byte{})
|
| 122 |
+
if err != nil {
|
| 123 |
+
return &DataCommitteeBackend{}, nil, nil, err
|
| 124 |
+
}
|
| 125 |
+
client.Commit()
|
| 126 |
+
|
| 127 |
+
c := &DataCommitteeBackend{
|
| 128 |
+
dataCommitteeContract: da,
|
| 129 |
+
}
|
| 130 |
+
return c, client, da, nil
|
| 131 |
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package dataavailability
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"math/big"
|
| 6 |
+
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
+
"github.com/ethereum/go-ethereum/common"
|
| 10 |
+
"github.com/jackc/pgx/v4"
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
// DABackender is an interface for components that store and retrieve batch data
|
| 14 |
+
type DABackender interface {
|
| 15 |
+
SequenceRetriever
|
| 16 |
+
SequenceSender
|
| 17 |
+
// Init initializes the DABackend
|
| 18 |
+
Init() error
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
// SequenceSender is used to send provided sequence of batches
|
| 22 |
+
type SequenceSender interface {
|
| 23 |
+
// PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage
|
| 24 |
+
// as expected by the contract
|
| 25 |
+
PostSequence(ctx context.Context, batchesData [][]byte) ([]byte, error)
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
// SequenceRetriever is used to retrieve batch data
|
| 29 |
+
type SequenceRetriever interface {
|
| 30 |
+
// GetSequence retrieves the sequence data from the data availability backend
|
| 31 |
+
GetSequence(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error)
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// === Internal interfaces ===
|
| 35 |
+
|
| 36 |
+
type stateInterface interface {
|
| 37 |
+
GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error)
|
| 38 |
+
GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 39 |
+
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 40 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
// BatchDataProvider is used to retrieve batch data
|
| 44 |
+
type BatchDataProvider interface {
|
| 45 |
+
// GetBatchL2Data retrieve the data of a batch from the DA backend. The returned data must be the pre-image of the hash
|
| 46 |
+
GetBatchL2Data(batchNum []uint64, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error)
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// DataManager is an interface for components that send and retrieve batch data
|
| 50 |
+
type DataManager interface {
|
| 51 |
+
BatchDataProvider
|
| 52 |
+
SequenceSender
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
// ZKEVMClientTrustedBatchesGetter contains the methods required to interact with zkEVM-RPC
|
| 56 |
+
type ZKEVMClientTrustedBatchesGetter interface {
|
| 57 |
+
BatchByNumber(ctx context.Context, number *big.Int) (*types.Batch, error)
|
| 58 |
+
BatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error)
|
| 59 |
+
ForcedBatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error)
|
| 60 |
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- +migrate Down
|
| 2 |
+
DROP TABLE IF EXISTS pool.acl CASCADE;
|
| 3 |
+
DROP TABLE IF EXISTS pool.policy CASCADE;
|
| 4 |
+
|
| 5 |
+
-- +migrate Up
|
| 6 |
+
CREATE TABLE pool.policy
|
| 7 |
+
(
|
| 8 |
+
name VARCHAR PRIMARY KEY,
|
| 9 |
+
allow BOOLEAN NOT NULL DEFAULT false
|
| 10 |
+
);
|
| 11 |
+
|
| 12 |
+
INSERT INTO pool.policy (name, allow) VALUES ('send_tx', false);
|
| 13 |
+
INSERT INTO pool.policy (name, allow) VALUES ('deploy', false);
|
| 14 |
+
|
| 15 |
+
CREATE TABLE pool.acl
|
| 16 |
+
(
|
| 17 |
+
address VARCHAR,
|
| 18 |
+
policy VARCHAR,
|
| 19 |
+
PRIMARY KEY (address, policy)
|
| 20 |
+
);
|
|
@@ -8,19 +8,21 @@
|
|
| 8 |
"github.com/stretchr/testify/assert"
|
| 9 |
)
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
// this migration changes length of the token name
|
| 12 |
-
type migrationTest0013 struct
|
| 13 |
-
blockHashValue string
|
| 14 |
-
mainExitRootValue string
|
| 15 |
-
rollupExitRootValue string
|
| 16 |
-
globalExitRootValue string
|
| 17 |
-
previousBlockHashValue string
|
| 18 |
-
l1InfoRootValue string
|
| 19 |
-
}
|
| 20 |
|
| 21 |
func (m migrationTest0013) insertBlock(blockNumber uint64, db *sql.DB) error {
|
| 22 |
const addBlock = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES ($1, $2, $3)"
|
| 23 |
-
if _, err := db.Exec(addBlock, blockNumber, time.Now(),
|
| 24 |
return err
|
| 25 |
}
|
| 26 |
return nil
|
|
@@ -43,10 +45,10 @@
|
|
| 43 |
if err = m.insertBlock(uint64(124), db); err != nil {
|
| 44 |
return err
|
| 45 |
}
|
| 46 |
-
if err = m.insertRowInOldTable(db, []interface{}{123, time.Now(),
|
| 47 |
return err
|
| 48 |
}
|
| 49 |
-
if err = m.insertRowInOldTable(db, []interface{}{124, time.Now(),
|
| 50 |
return err
|
| 51 |
}
|
| 52 |
|
|
@@ -111,16 +113,16 @@
|
|
| 111 |
assert.NoError(t, err)
|
| 112 |
err = m.insertBlock(uint64(127), db)
|
| 113 |
assert.NoError(t, err)
|
| 114 |
-
prevBlockHash :=
|
| 115 |
-
l1InfoRoot :=
|
| 116 |
-
err = m.insertRowInMigratedTable(db, []interface{}{125, time.Now(),
|
| 117 |
assert.NoError(t, err)
|
| 118 |
// insert duplicated l1_info_root
|
| 119 |
-
err = m.insertRowInMigratedTable(db, []interface{}{126, time.Now(),
|
| 120 |
assert.Error(t, err)
|
| 121 |
|
| 122 |
// insert in the old way must work
|
| 123 |
-
err = m.insertRowInOldTable(db, []interface{}{127, time.Now(),
|
| 124 |
assert.NoError(t, err)
|
| 125 |
|
| 126 |
sqlSelect := `SELECT prev_block_hash, l1_info_root FROM state.exit_root WHERE l1_info_tree_index = $1`
|
|
@@ -183,13 +185,5 @@
|
|
| 183 |
}
|
| 184 |
|
| 185 |
func TestMigration0013(t *testing.T) {
|
| 186 |
-
|
| 187 |
-
blockHashValue: "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1",
|
| 188 |
-
mainExitRootValue: "0x83fc198de31e1b2b1a8212d2430fbb7766c13d9ad305637dea3759065606475d",
|
| 189 |
-
rollupExitRootValue: "0xadb91a6a1fce56eaea561002bc9a993f4e65a7710bd72f4eee3067cbd73a743c",
|
| 190 |
-
globalExitRootValue: "0x5bf4af1a651a2a74b36e6eb208481f94c69fc959f756223dfa49608061937585",
|
| 191 |
-
previousBlockHashValue: "0xe865e912b504572a4d80ad018e29797e3c11f00bf9ae2549548a25779c9d7e57",
|
| 192 |
-
l1InfoRootValue: "0x2b9484b83c6398033241865b015fb9430eb3e159182a6075d00c924845cc393e",
|
| 193 |
-
}
|
| 194 |
-
runMigrationTest(t, 13, m)
|
| 195 |
}
|
|
|
|
| 8 |
"github.com/stretchr/testify/assert"
|
| 9 |
)
|
| 10 |
|
| 11 |
+
const (
|
| 12 |
+
blockHashValue = "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1"
|
| 13 |
+
mainExitRootValue = "0x83fc198de31e1b2b1a8212d2430fbb7766c13d9ad305637dea3759065606475d"
|
| 14 |
+
rollupExitRootValue = "0xadb91a6a1fce56eaea561002bc9a993f4e65a7710bd72f4eee3067cbd73a743c"
|
| 15 |
+
globalExitRootValue = "0x5bf4af1a651a2a74b36e6eb208481f94c69fc959f756223dfa49608061937585"
|
| 16 |
+
previousBlockHashValue = "0xe865e912b504572a4d80ad018e29797e3c11f00bf9ae2549548a25779c9d7e57"
|
| 17 |
+
l1InfoRootValue = "0x2b9484b83c6398033241865b015fb9430eb3e159182a6075d00c924845cc393e"
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
// this migration changes length of the token name
|
| 21 |
+
type migrationTest0013 struct{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
func (m migrationTest0013) insertBlock(blockNumber uint64, db *sql.DB) error {
|
| 24 |
const addBlock = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES ($1, $2, $3)"
|
| 25 |
+
if _, err := db.Exec(addBlock, blockNumber, time.Now(), blockHashValue); err != nil {
|
| 26 |
return err
|
| 27 |
}
|
| 28 |
return nil
|
|
|
|
| 45 |
if err = m.insertBlock(uint64(124), db); err != nil {
|
| 46 |
return err
|
| 47 |
}
|
| 48 |
+
if err = m.insertRowInOldTable(db, []interface{}{123, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue}); err != nil {
|
| 49 |
return err
|
| 50 |
}
|
| 51 |
+
if err = m.insertRowInOldTable(db, []interface{}{124, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue}); err != nil {
|
| 52 |
return err
|
| 53 |
}
|
| 54 |
|
|
|
|
| 113 |
assert.NoError(t, err)
|
| 114 |
err = m.insertBlock(uint64(127), db)
|
| 115 |
assert.NoError(t, err)
|
| 116 |
+
prevBlockHash := previousBlockHashValue
|
| 117 |
+
l1InfoRoot := l1InfoRootValue
|
| 118 |
+
err = m.insertRowInMigratedTable(db, []interface{}{125, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue, prevBlockHash, l1InfoRoot, 1})
|
| 119 |
assert.NoError(t, err)
|
| 120 |
// insert duplicated l1_info_root
|
| 121 |
+
err = m.insertRowInMigratedTable(db, []interface{}{126, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue, prevBlockHash, l1InfoRoot, 1})
|
| 122 |
assert.Error(t, err)
|
| 123 |
|
| 124 |
// insert in the old way must work
|
| 125 |
+
err = m.insertRowInOldTable(db, []interface{}{127, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue})
|
| 126 |
assert.NoError(t, err)
|
| 127 |
|
| 128 |
sqlSelect := `SELECT prev_block_hash, l1_info_root FROM state.exit_root WHERE l1_info_tree_index = $1`
|
|
|
|
| 185 |
}
|
| 186 |
|
| 187 |
func TestMigration0013(t *testing.T) {
|
| 188 |
+
runMigrationTest(t, 13, migrationTest0013{})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
}
|
|
@@ -1,81 +1,25 @@
|
|
| 1 |
-- +migrate Up
|
| 2 |
-
CREATE TABLE state.blob_inner
|
| 3 |
-
(
|
| 4 |
-
blob_inner_num BIGINT PRIMARY KEY,
|
| 5 |
-
data BYTEA,
|
| 6 |
-
block_num BIGINT NOT NULL REFERENCES state.block (block_num) ON DELETE CASCADE
|
| 7 |
-
);
|
| 8 |
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
ALTER TABLE IF EXISTS state.proof RENAME TO batch_proof;
|
| 15 |
-
|
| 16 |
-
ALTER TABLE state.batch_proof
|
| 17 |
-
ADD COLUMN IF NOT EXISTS blob_inner_num BIGINT; -- NOT NULL REFERENCES state.blob_inner (blob_inner_num) ON DELETE CASCADE;
|
| 18 |
-
|
| 19 |
-
CREATE TABLE state.blob_inner_proof
|
| 20 |
-
(
|
| 21 |
-
blob_inner_num BIGINT NOT NULL, -- REFERENCES state.blob_inner (blob_inner_num) ON DELETE CASCADE,
|
| 22 |
-
proof_id VARCHAR,
|
| 23 |
-
proof VARCHAR,
|
| 24 |
-
input_prover VARCHAR,
|
| 25 |
-
prover VARCHAR,
|
| 26 |
-
prover_id VARCHAR,
|
| 27 |
-
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 28 |
-
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 29 |
-
generating_since TIMESTAMP WITH TIME ZONE,
|
| 30 |
-
PRIMARY KEY (blob_inner_num)
|
| 31 |
-
);
|
| 32 |
-
|
| 33 |
-
CREATE TABLE state.blob_outer_proof
|
| 34 |
-
(
|
| 35 |
-
blob_outer_num BIGINT NOT NULL, -- REFERENCES state.blob_inner (blob_inner_num) ON DELETE CASCADE,
|
| 36 |
-
blob_outer_num_final BIGINT NOT NULL, -- REFERENCES state.blob_inner (blob_inner_num) ON DELETE CASCADE,
|
| 37 |
-
proof_id VARCHAR,
|
| 38 |
-
proof VARCHAR,
|
| 39 |
-
input_prover VARCHAR,
|
| 40 |
-
prover VARCHAR,
|
| 41 |
-
prover_id VARCHAR,
|
| 42 |
-
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 43 |
-
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 44 |
-
generating_since TIMESTAMP WITH TIME ZONE,
|
| 45 |
-
PRIMARY KEY (blob_outer_num, blob_outer_num_final)
|
| 46 |
-
);
|
| 47 |
|
| 48 |
-- +migrate Down
|
| 49 |
-
ALTER TABLE state.virtual_batch
|
| 50 |
-
DROP COLUMN IF EXISTS blob_inner_num,
|
| 51 |
-
DROP COLUMN IF EXISTS prev_l1_it_root,
|
| 52 |
-
DROP COLUMN IF EXISTS prev_l1_it_index;
|
| 53 |
-
|
| 54 |
-
DROP TABLE state.blob_outer_proof;
|
| 55 |
-
|
| 56 |
-
DROP TABLE state.blob_inner_proof;
|
| 57 |
-
|
| 58 |
-
DROP TABLE state.batch_proof;
|
| 59 |
-
|
| 60 |
-
DROP TABLE state.blob_inner;
|
| 61 |
-
|
| 62 |
-
CREATE TABLE state.proof
|
| 63 |
-
(
|
| 64 |
-
batch_num BIGINT NOT NULL REFERENCES state.batch (batch_num) ON DELETE CASCADE,
|
| 65 |
-
batch_num_final BIGINT NOT NULL REFERENCES state.batch (batch_num) ON DELETE CASCADE,
|
| 66 |
-
proof_id VARCHAR,
|
| 67 |
-
proof VARCHAR,
|
| 68 |
-
input_prover VARCHAR,
|
| 69 |
-
prover VARCHAR,
|
| 70 |
-
prover_id VARCHAR,
|
| 71 |
-
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 72 |
-
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 73 |
-
generating_since TIMESTAMP WITH TIME ZONE,
|
| 74 |
-
PRIMARY KEY (batch_num, batch_num_final)
|
| 75 |
-
);
|
| 76 |
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
DROP COLUMN IF EXISTS prev_l1_it_root,
|
| 80 |
-
DROP COLUMN IF EXISTS prev_l1_it_index;
|
| 81 |
-
|
|
|
|
| 1 |
-- +migrate Up
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
+
-- the update below fix the wrong receipt TX indexes
|
| 4 |
+
WITH map_fix_tx_index AS (
|
| 5 |
+
SELECT t.l2_block_num AS block_num
|
| 6 |
+
, t.hash AS tx_hash
|
| 7 |
+
, r.tx_index AS current_index
|
| 8 |
+
, (ROW_NUMBER() OVER (PARTITION BY t.l2_block_num ORDER BY r.tx_index))-1 AS correct_index
|
| 9 |
+
FROM state.receipt r
|
| 10 |
+
INNER JOIN state."transaction" t
|
| 11 |
+
ON t.hash = r.tx_hash
|
| 12 |
+
)
|
| 13 |
+
UPDATE state.receipt AS r
|
| 14 |
+
SET tx_index = m.correct_index
|
| 15 |
+
FROM map_fix_tx_index m
|
| 16 |
+
WHERE m.block_num = r.block_num
|
| 17 |
+
AND m.tx_hash = r.tx_hash
|
| 18 |
+
AND m.current_index = r.tx_index
|
| 19 |
+
AND m.current_index != m.correct_index;
|
| 20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
-- +migrate Down
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
+
-- no action is needed, the data fixed by the
|
| 25 |
+
-- migrate up must remain fixed
|
|
|
|
|
|
|
|
|
|
@@ -4,116 +4,142 @@
|
|
| 4 |
"database/sql"
|
| 5 |
"testing"
|
| 6 |
|
| 7 |
-
"github.com/
|
|
|
|
|
|
|
| 8 |
)
|
| 9 |
|
| 10 |
-
type
|
| 11 |
-
|
|
|
|
| 12 |
}
|
| 13 |
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
VALUES (1,'0x0001', '0x0001', '0x0001', '0x0001', now(), '0x0001', null, null, true)`
|
| 18 |
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
}
|
| 23 |
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
|
| 28 |
-
|
| 29 |
-
|
|
|
|
| 30 |
return err
|
| 31 |
}
|
| 32 |
|
| 33 |
-
const
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
if err != nil {
|
| 37 |
return err
|
| 38 |
}
|
| 39 |
|
| 40 |
-
const
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
}
|
| 46 |
|
| 47 |
return nil
|
| 48 |
}
|
| 49 |
|
| 50 |
func (m migrationTest0019) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 51 |
-
|
| 52 |
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
_, err := db.Exec(insertBlobInner)
|
| 56 |
-
assert.NoError(t, err)
|
| 57 |
-
|
| 58 |
-
const insertBatch1 = `
|
| 59 |
-
INSERT INTO state.virtual_batch (batch_num, tx_hash, coinbase, block_num, sequencer_addr, timestamp_batch_etrog, l1_info_root, blob_inner_num, prev_l1_it_root, prev_l1_it_index)
|
| 60 |
-
VALUES (1,'0x0001', '0x0001', 1, '0x0001', now(), '0x0001', 1, '0x0001', 1)`
|
| 61 |
-
|
| 62 |
-
_, err = db.Exec(insertBatch1)
|
| 63 |
-
assert.NoError(t, err)
|
| 64 |
-
|
| 65 |
-
const insertBatch2 = `
|
| 66 |
-
INSERT INTO state.virtual_batch (batch_num, tx_hash, coinbase, block_num, sequencer_addr, timestamp_batch_etrog, l1_info_root, blob_inner_num, prev_l1_it_root, prev_l1_it_index)
|
| 67 |
-
VALUES (2,'0x0002', '0x0002', 2, '0x0002', now(), '0x0002', 1, '0x0002', 2)`
|
| 68 |
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
}
|
| 72 |
|
| 73 |
func (m migrationTest0019) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
m.AssertNewAndRemovedItemsAfterMigrationDown(t, db)
|
| 77 |
-
|
| 78 |
-
// Check column blob_inner_num doesn't exists in state.virtual_batch table
|
| 79 |
-
const getBlobInnerNumColumn = `SELECT count(*) FROM information_schema.columns WHERE table_name='virtual_batch' and column_name='blob_inner_num'`
|
| 80 |
-
row := db.QueryRow(getBlobInnerNumColumn)
|
| 81 |
-
assert.NoError(t, row.Scan(&result))
|
| 82 |
-
assert.Equal(t, 0, result)
|
| 83 |
-
|
| 84 |
-
// Check column prev_l1_it_root doesn't exists in state.virtual_batch table
|
| 85 |
-
const getPrevL1ITRootColumn = `SELECT count(*) FROM information_schema.columns WHERE table_name='virtual_batch' and column_name='prev_l1_it_root'`
|
| 86 |
-
row = db.QueryRow(getPrevL1ITRootColumn)
|
| 87 |
-
assert.NoError(t, row.Scan(&result))
|
| 88 |
-
assert.Equal(t, 0, result)
|
| 89 |
-
|
| 90 |
-
// Check column prev_l1_it_index doesn't exists in state.virtual_batch table
|
| 91 |
-
const getPrevL1ITIndexColumn = `SELECT count(*) FROM information_schema.columns WHERE table_name='virtual_batch' and column_name='prev_l1_it_index'`
|
| 92 |
-
row = db.QueryRow(getPrevL1ITIndexColumn)
|
| 93 |
-
assert.NoError(t, row.Scan(&result))
|
| 94 |
-
assert.Equal(t, 0, result)
|
| 95 |
}
|
| 96 |
|
| 97 |
func TestMigration0019(t *testing.T) {
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
},
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
{
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
| 109 |
},
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
{
|
| 113 |
-
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
},
|
| 116 |
},
|
| 117 |
-
}
|
| 118 |
-
runMigrationTest(t, 19, m)
|
| 119 |
}
|
|
|
|
| 4 |
"database/sql"
|
| 5 |
"testing"
|
| 6 |
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 8 |
+
"github.com/ethereum/go-ethereum/common"
|
| 9 |
+
"github.com/stretchr/testify/require"
|
| 10 |
)
|
| 11 |
|
| 12 |
+
type migrationTest0019TestCase struct {
|
| 13 |
+
Name string
|
| 14 |
+
Block migrationTest0019TestCaseBlock
|
| 15 |
}
|
| 16 |
|
| 17 |
+
type migrationTest0019TestCaseBlock struct {
|
| 18 |
+
Transactions []migrationTest0019TestCaseTransaction
|
| 19 |
+
}
|
|
|
|
| 20 |
|
| 21 |
+
type migrationTest0019TestCaseTransaction struct {
|
| 22 |
+
CurrentIndex uint
|
| 23 |
+
}
|
|
|
|
| 24 |
|
| 25 |
+
type migrationTest0019 struct {
|
| 26 |
+
TestCases []migrationTest0019TestCase
|
| 27 |
+
}
|
| 28 |
|
| 29 |
+
func (m migrationTest0019) InsertData(db *sql.DB) error {
|
| 30 |
+
const addBlock0 = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES (0, now(), '0x0')"
|
| 31 |
+
if _, err := db.Exec(addBlock0); err != nil {
|
| 32 |
return err
|
| 33 |
}
|
| 34 |
|
| 35 |
+
const addBatch0 = `
|
| 36 |
+
INSERT INTO state.batch (batch_num, global_exit_root, local_exit_root, acc_input_hash, state_root, timestamp, coinbase, raw_txs_data, forced_batch_num, wip)
|
| 37 |
+
VALUES (0,'0x0000', '0x0000', '0x0000', '0x0000', now(), '0x0000', null, null, true)`
|
| 38 |
+
if _, err := db.Exec(addBatch0); err != nil {
|
| 39 |
return err
|
| 40 |
}
|
| 41 |
|
| 42 |
+
const addL2Block = "INSERT INTO state.l2block (block_num, block_hash, header, uncles, parent_hash, state_root, received_at, batch_num, created_at) VALUES ($1, $2, '{}', '{}', '0x0', '0x0', now(), 0, now())"
|
| 43 |
+
const addTransaction = "INSERT INTO state.transaction (hash, encoded, decoded, l2_block_num, effective_percentage, l2_hash) VALUES ($1, 'ABCDEF', '{}', $2, 255, $1)"
|
| 44 |
+
const addReceipt = "INSERT INTO state.receipt (tx_hash, type, post_state, status, cumulative_gas_used, gas_used, effective_gas_price, block_num, tx_index, contract_address) VALUES ($1, 1, null, 1, 1234, 1234, 1, $2, $3, '')"
|
| 45 |
+
|
| 46 |
+
txUnique := 0
|
| 47 |
+
for tci, testCase := range m.TestCases {
|
| 48 |
+
blockNum := uint64(tci + 1)
|
| 49 |
+
blockHash := common.HexToHash(hex.EncodeUint64(blockNum)).String()
|
| 50 |
+
if _, err := db.Exec(addL2Block, blockNum, blockHash); err != nil {
|
| 51 |
+
return err
|
| 52 |
+
}
|
| 53 |
+
for _, tx := range testCase.Block.Transactions {
|
| 54 |
+
txUnique++
|
| 55 |
+
txHash := common.HexToHash(hex.EncodeUint64(uint64(txUnique))).String()
|
| 56 |
+
if _, err := db.Exec(addTransaction, txHash, blockNum); err != nil {
|
| 57 |
+
return err
|
| 58 |
+
}
|
| 59 |
+
if _, err := db.Exec(addReceipt, txHash, blockNum, tx.CurrentIndex); err != nil {
|
| 60 |
+
return err
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
}
|
| 64 |
|
| 65 |
return nil
|
| 66 |
}
|
| 67 |
|
| 68 |
func (m migrationTest0019) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 69 |
+
const getReceiptsByBlock = "SELECT r.tx_index FROM state.receipt r WHERE r.block_num = $1 ORDER BY r.tx_index"
|
| 70 |
|
| 71 |
+
for tci := range m.TestCases {
|
| 72 |
+
blockNum := uint64(tci + 1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
+
rows, err := db.Query(getReceiptsByBlock, blockNum)
|
| 75 |
+
require.NoError(t, err)
|
| 76 |
+
|
| 77 |
+
var expectedIndex = uint(0)
|
| 78 |
+
var txIndex uint
|
| 79 |
+
for rows.Next() {
|
| 80 |
+
err := rows.Scan(&txIndex)
|
| 81 |
+
require.NoError(t, err)
|
| 82 |
+
require.Equal(t, expectedIndex, txIndex)
|
| 83 |
+
expectedIndex++
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
}
|
| 87 |
|
| 88 |
func (m migrationTest0019) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 89 |
+
m.RunAssertsAfterMigrationUp(t, db)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
}
|
| 91 |
|
| 92 |
func TestMigration0019(t *testing.T) {
|
| 93 |
+
runMigrationTest(t, 19, migrationTest0019{
|
| 94 |
+
TestCases: []migrationTest0019TestCase{
|
| 95 |
+
{
|
| 96 |
+
Name: "single tx with correct index",
|
| 97 |
+
Block: migrationTest0019TestCaseBlock{
|
| 98 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 99 |
+
{CurrentIndex: 0},
|
| 100 |
+
},
|
| 101 |
+
},
|
| 102 |
},
|
| 103 |
+
{
|
| 104 |
+
Name: "multiple txs indexes are correct",
|
| 105 |
+
Block: migrationTest0019TestCaseBlock{
|
| 106 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 107 |
+
{CurrentIndex: 0},
|
| 108 |
+
{CurrentIndex: 1},
|
| 109 |
+
{CurrentIndex: 2},
|
| 110 |
+
},
|
| 111 |
+
},
|
| 112 |
},
|
| 113 |
+
{
|
| 114 |
+
Name: "single tx with wrong tx index",
|
| 115 |
+
Block: migrationTest0019TestCaseBlock{
|
| 116 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 117 |
+
{CurrentIndex: 3},
|
| 118 |
+
},
|
| 119 |
+
},
|
| 120 |
+
},
|
| 121 |
+
{
|
| 122 |
+
Name: "multiple txs missing 0 index",
|
| 123 |
+
Block: migrationTest0019TestCaseBlock{
|
| 124 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 125 |
+
{CurrentIndex: 1},
|
| 126 |
+
{CurrentIndex: 2},
|
| 127 |
+
{CurrentIndex: 3},
|
| 128 |
+
{CurrentIndex: 4},
|
| 129 |
+
},
|
| 130 |
+
},
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
Name: "multiple has index 0 but also txs index gap",
|
| 134 |
+
Block: migrationTest0019TestCaseBlock{
|
| 135 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 136 |
+
{CurrentIndex: 0},
|
| 137 |
+
{CurrentIndex: 2},
|
| 138 |
+
{CurrentIndex: 4},
|
| 139 |
+
{CurrentIndex: 6},
|
| 140 |
+
},
|
| 141 |
+
},
|
| 142 |
},
|
| 143 |
},
|
| 144 |
+
})
|
|
|
|
| 145 |
}
|
|
@@ -1,25 +0,0 @@
|
|
| 1 |
-
-- +migrate Up
|
| 2 |
-
|
| 3 |
-
-- the update below fix the wrong receipt TX indexes
|
| 4 |
-
WITH map_fix_tx_index AS (
|
| 5 |
-
SELECT t.l2_block_num AS block_num
|
| 6 |
-
, t.hash AS tx_hash
|
| 7 |
-
, r.tx_index AS current_index
|
| 8 |
-
, (ROW_NUMBER() OVER (PARTITION BY t.l2_block_num ORDER BY r.tx_index))-1 AS correct_index
|
| 9 |
-
FROM state.receipt r
|
| 10 |
-
INNER JOIN state."transaction" t
|
| 11 |
-
ON t.hash = r.tx_hash
|
| 12 |
-
)
|
| 13 |
-
UPDATE state.receipt AS r
|
| 14 |
-
SET tx_index = m.correct_index
|
| 15 |
-
FROM map_fix_tx_index m
|
| 16 |
-
WHERE m.block_num = r.block_num
|
| 17 |
-
AND m.tx_hash = r.tx_hash
|
| 18 |
-
AND m.current_index = r.tx_index
|
| 19 |
-
AND m.current_index != m.correct_index;
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
-- +migrate Down
|
| 23 |
-
|
| 24 |
-
-- no action is needed, the data fixed by the
|
| 25 |
-
-- migrate up must remain fixed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,145 +0,0 @@
|
|
| 1 |
-
package migrations_test
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"database/sql"
|
| 5 |
-
"testing"
|
| 6 |
-
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 8 |
-
"github.com/ethereum/go-ethereum/common"
|
| 9 |
-
"github.com/stretchr/testify/require"
|
| 10 |
-
)
|
| 11 |
-
|
| 12 |
-
type migrationTest0021TestCase struct {
|
| 13 |
-
Name string
|
| 14 |
-
Block migrationTest0021TestCaseBlock
|
| 15 |
-
}
|
| 16 |
-
|
| 17 |
-
type migrationTest0021TestCaseBlock struct {
|
| 18 |
-
Transactions []migrationTest0021TestCaseTransaction
|
| 19 |
-
}
|
| 20 |
-
|
| 21 |
-
type migrationTest0021TestCaseTransaction struct {
|
| 22 |
-
CurrentIndex uint
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
type migrationTest0021 struct {
|
| 26 |
-
TestCases []migrationTest0021TestCase
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
func (m migrationTest0021) InsertData(db *sql.DB) error {
|
| 30 |
-
const addBlock0 = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES (0, now(), '0x0')"
|
| 31 |
-
if _, err := db.Exec(addBlock0); err != nil {
|
| 32 |
-
return err
|
| 33 |
-
}
|
| 34 |
-
|
| 35 |
-
const addBatch0 = `
|
| 36 |
-
INSERT INTO state.batch (batch_num, global_exit_root, local_exit_root, acc_input_hash, state_root, timestamp, coinbase, raw_txs_data, forced_batch_num, wip)
|
| 37 |
-
VALUES (0,'0x0000', '0x0000', '0x0000', '0x0000', now(), '0x0000', null, null, true)`
|
| 38 |
-
if _, err := db.Exec(addBatch0); err != nil {
|
| 39 |
-
return err
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
const addL2Block = "INSERT INTO state.l2block (block_num, block_hash, header, uncles, parent_hash, state_root, received_at, batch_num, created_at) VALUES ($1, $2, '{}', '{}', '0x0', '0x0', now(), 0, now())"
|
| 43 |
-
const addTransaction = "INSERT INTO state.transaction (hash, encoded, decoded, l2_block_num, effective_percentage, l2_hash) VALUES ($1, 'ABCDEF', '{}', $2, 255, $1)"
|
| 44 |
-
const addReceipt = "INSERT INTO state.receipt (tx_hash, type, post_state, status, cumulative_gas_used, gas_used, effective_gas_price, block_num, tx_index, contract_address) VALUES ($1, 1, null, 1, 1234, 1234, 1, $2, $3, '')"
|
| 45 |
-
|
| 46 |
-
txUnique := 0
|
| 47 |
-
for tci, testCase := range m.TestCases {
|
| 48 |
-
blockNum := uint64(tci + 1)
|
| 49 |
-
blockHash := common.HexToHash(hex.EncodeUint64(blockNum)).String()
|
| 50 |
-
if _, err := db.Exec(addL2Block, blockNum, blockHash); err != nil {
|
| 51 |
-
return err
|
| 52 |
-
}
|
| 53 |
-
for _, tx := range testCase.Block.Transactions {
|
| 54 |
-
txUnique++
|
| 55 |
-
txHash := common.HexToHash(hex.EncodeUint64(uint64(txUnique))).String()
|
| 56 |
-
if _, err := db.Exec(addTransaction, txHash, blockNum); err != nil {
|
| 57 |
-
return err
|
| 58 |
-
}
|
| 59 |
-
if _, err := db.Exec(addReceipt, txHash, blockNum, tx.CurrentIndex); err != nil {
|
| 60 |
-
return err
|
| 61 |
-
}
|
| 62 |
-
}
|
| 63 |
-
}
|
| 64 |
-
|
| 65 |
-
return nil
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
func (m migrationTest0021) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 69 |
-
const getReceiptsByBlock = "SELECT r.tx_index FROM state.receipt r WHERE r.block_num = $1 ORDER BY r.tx_index"
|
| 70 |
-
|
| 71 |
-
for tci := range m.TestCases {
|
| 72 |
-
blockNum := uint64(tci + 1)
|
| 73 |
-
|
| 74 |
-
rows, err := db.Query(getReceiptsByBlock, blockNum)
|
| 75 |
-
require.NoError(t, err)
|
| 76 |
-
|
| 77 |
-
var expectedIndex = uint(0)
|
| 78 |
-
var txIndex uint
|
| 79 |
-
for rows.Next() {
|
| 80 |
-
err := rows.Scan(&txIndex)
|
| 81 |
-
require.NoError(t, err)
|
| 82 |
-
require.Equal(t, expectedIndex, txIndex)
|
| 83 |
-
expectedIndex++
|
| 84 |
-
}
|
| 85 |
-
}
|
| 86 |
-
}
|
| 87 |
-
|
| 88 |
-
func (m migrationTest0021) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 89 |
-
m.RunAssertsAfterMigrationUp(t, db)
|
| 90 |
-
}
|
| 91 |
-
|
| 92 |
-
func TestMigration0021(t *testing.T) {
|
| 93 |
-
runMigrationTest(t, 21, migrationTest0021{
|
| 94 |
-
TestCases: []migrationTest0021TestCase{
|
| 95 |
-
{
|
| 96 |
-
Name: "single tx with correct index",
|
| 97 |
-
Block: migrationTest0021TestCaseBlock{
|
| 98 |
-
Transactions: []migrationTest0021TestCaseTransaction{
|
| 99 |
-
{CurrentIndex: 0},
|
| 100 |
-
},
|
| 101 |
-
},
|
| 102 |
-
},
|
| 103 |
-
{
|
| 104 |
-
Name: "multiple txs indexes are correct",
|
| 105 |
-
Block: migrationTest0021TestCaseBlock{
|
| 106 |
-
Transactions: []migrationTest0021TestCaseTransaction{
|
| 107 |
-
{CurrentIndex: 0},
|
| 108 |
-
{CurrentIndex: 1},
|
| 109 |
-
{CurrentIndex: 2},
|
| 110 |
-
},
|
| 111 |
-
},
|
| 112 |
-
},
|
| 113 |
-
{
|
| 114 |
-
Name: "single tx with wrong tx index",
|
| 115 |
-
Block: migrationTest0021TestCaseBlock{
|
| 116 |
-
Transactions: []migrationTest0021TestCaseTransaction{
|
| 117 |
-
{CurrentIndex: 3},
|
| 118 |
-
},
|
| 119 |
-
},
|
| 120 |
-
},
|
| 121 |
-
{
|
| 122 |
-
Name: "multiple txs missing 0 index",
|
| 123 |
-
Block: migrationTest0021TestCaseBlock{
|
| 124 |
-
Transactions: []migrationTest0021TestCaseTransaction{
|
| 125 |
-
{CurrentIndex: 1},
|
| 126 |
-
{CurrentIndex: 2},
|
| 127 |
-
{CurrentIndex: 3},
|
| 128 |
-
{CurrentIndex: 4},
|
| 129 |
-
},
|
| 130 |
-
},
|
| 131 |
-
},
|
| 132 |
-
{
|
| 133 |
-
Name: "multiple has index 0 but also txs index gap",
|
| 134 |
-
Block: migrationTest0021TestCaseBlock{
|
| 135 |
-
Transactions: []migrationTest0021TestCaseTransaction{
|
| 136 |
-
{CurrentIndex: 0},
|
| 137 |
-
{CurrentIndex: 2},
|
| 138 |
-
{CurrentIndex: 4},
|
| 139 |
-
{CurrentIndex: 6},
|
| 140 |
-
},
|
| 141 |
-
},
|
| 142 |
-
},
|
| 143 |
-
},
|
| 144 |
-
})
|
| 145 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,12 +0,0 @@
|
|
| 1 |
-
-- +migrate Up
|
| 2 |
-
|
| 3 |
-
-- +migrate Up
|
| 4 |
-
ALTER TABLE state.exit_root
|
| 5 |
-
ADD COLUMN IF NOT EXISTS l1_info_tree_recursive_index BIGINT DEFAULT NULL UNIQUE;
|
| 6 |
-
CREATE INDEX IF NOT EXISTS idx_exit_root_l1_info_tree_recursive_index ON state.exit_root (l1_info_tree_recursive_index);
|
| 7 |
-
|
| 8 |
-
-- +migrate Down
|
| 9 |
-
ALTER TABLE state.exit_root
|
| 10 |
-
DROP COLUMN IF EXISTS l1_info_tree_recursive_index;
|
| 11 |
-
DROP INDEX IF EXISTS state.idx_exit_root_l1_info_tree_recursive_index;
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,106 +0,0 @@
|
|
| 1 |
-
package migrations_test
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"database/sql"
|
| 5 |
-
"testing"
|
| 6 |
-
"time"
|
| 7 |
-
|
| 8 |
-
"github.com/stretchr/testify/assert"
|
| 9 |
-
)
|
| 10 |
-
|
| 11 |
-
type migrationTest0022 struct {
|
| 12 |
-
migrationBase
|
| 13 |
-
|
| 14 |
-
blockHashValue string
|
| 15 |
-
mainExitRootValue string
|
| 16 |
-
rollupExitRootValue string
|
| 17 |
-
globalExitRootValue string
|
| 18 |
-
previousBlockHashValue string
|
| 19 |
-
l1InfoRootValue string
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
func (m migrationTest0022) insertBlock(blockNumber uint64, db *sql.DB) error {
|
| 23 |
-
const addBlock = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES ($1, $2, $3)"
|
| 24 |
-
if _, err := db.Exec(addBlock, blockNumber, time.Now(), m.blockHashValue); err != nil {
|
| 25 |
-
return err
|
| 26 |
-
}
|
| 27 |
-
return nil
|
| 28 |
-
}
|
| 29 |
-
|
| 30 |
-
func (m migrationTest0022) insertRowInOldTable(db *sql.DB, args ...interface{}) error {
|
| 31 |
-
sql := `
|
| 32 |
-
INSERT INTO state.exit_root (block_num, "timestamp", mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index)
|
| 33 |
-
VALUES ( $1, $2, $3, $4, $5, $6, $7, $8);`
|
| 34 |
-
|
| 35 |
-
_, err := db.Exec(sql, args...)
|
| 36 |
-
return err
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
func (m migrationTest0022) insertRowInMigratedTable(db *sql.DB, args ...interface{}) error {
|
| 40 |
-
sql := `
|
| 41 |
-
INSERT INTO state.exit_root (block_num, "timestamp", mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index, l1_info_tree_recursive_index)
|
| 42 |
-
VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9);`
|
| 43 |
-
|
| 44 |
-
_, err := db.Exec(sql, args...)
|
| 45 |
-
return err
|
| 46 |
-
}
|
| 47 |
-
|
| 48 |
-
func (m migrationTest0022) InsertData(db *sql.DB) error {
|
| 49 |
-
var err error
|
| 50 |
-
for i := uint64(1); i <= 6; i++ {
|
| 51 |
-
if err = m.insertBlock(i, db); err != nil {
|
| 52 |
-
return err
|
| 53 |
-
}
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
return nil
|
| 57 |
-
}
|
| 58 |
-
|
| 59 |
-
func (m migrationTest0022) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 60 |
-
m.AssertNewAndRemovedItemsAfterMigrationUp(t, db)
|
| 61 |
-
|
| 62 |
-
var nilL1InfoTreeIndex *uint = nil
|
| 63 |
-
err := m.insertRowInOldTable(db, 1, time.Now().UTC(), m.mainExitRootValue, m.rollupExitRootValue, m.globalExitRootValue, m.previousBlockHashValue, m.l1InfoRootValue, nilL1InfoTreeIndex)
|
| 64 |
-
assert.NoError(t, err)
|
| 65 |
-
|
| 66 |
-
err = m.insertRowInOldTable(db, 2, time.Now().UTC(), m.mainExitRootValue, m.rollupExitRootValue, m.globalExitRootValue, m.previousBlockHashValue, m.l1InfoRootValue, uint(1))
|
| 67 |
-
assert.NoError(t, err)
|
| 68 |
-
|
| 69 |
-
err = m.insertRowInMigratedTable(db, 3, time.Now().UTC(), m.mainExitRootValue, m.rollupExitRootValue, m.globalExitRootValue, m.previousBlockHashValue, m.l1InfoRootValue, nilL1InfoTreeIndex, 1)
|
| 70 |
-
assert.NoError(t, err)
|
| 71 |
-
}
|
| 72 |
-
|
| 73 |
-
func (m migrationTest0022) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 74 |
-
m.AssertNewAndRemovedItemsAfterMigrationDown(t, db)
|
| 75 |
-
|
| 76 |
-
var nilL1InfoTreeIndex *uint = nil
|
| 77 |
-
err := m.insertRowInOldTable(db, 4, time.Now().UTC(), m.mainExitRootValue, m.rollupExitRootValue, m.globalExitRootValue, m.previousBlockHashValue, m.l1InfoRootValue, nilL1InfoTreeIndex)
|
| 78 |
-
assert.NoError(t, err)
|
| 79 |
-
|
| 80 |
-
err = m.insertRowInOldTable(db, 5, time.Now().UTC(), m.mainExitRootValue, m.rollupExitRootValue, m.globalExitRootValue, m.previousBlockHashValue, m.l1InfoRootValue, uint(2))
|
| 81 |
-
assert.NoError(t, err)
|
| 82 |
-
|
| 83 |
-
err = m.insertRowInMigratedTable(db, 6, time.Now().UTC(), m.mainExitRootValue, m.rollupExitRootValue, m.globalExitRootValue, m.previousBlockHashValue, m.l1InfoRootValue, nilL1InfoTreeIndex, 2)
|
| 84 |
-
assert.Error(t, err)
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
func TestMigration0022(t *testing.T) {
|
| 88 |
-
m := migrationTest0022{
|
| 89 |
-
migrationBase: migrationBase{
|
| 90 |
-
newIndexes: []string{
|
| 91 |
-
"idx_exit_root_l1_info_tree_recursive_index",
|
| 92 |
-
},
|
| 93 |
-
newColumns: []columnMetadata{
|
| 94 |
-
{"state", "exit_root", "l1_info_tree_recursive_index"},
|
| 95 |
-
},
|
| 96 |
-
},
|
| 97 |
-
|
| 98 |
-
blockHashValue: "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1",
|
| 99 |
-
mainExitRootValue: "0x83fc198de31e1b2b1a8212d2430fbb7766c13d9ad305637dea3759065606475d",
|
| 100 |
-
rollupExitRootValue: "0xadb91a6a1fce56eaea561002bc9a993f4e65a7710bd72f4eee3067cbd73a743c",
|
| 101 |
-
globalExitRootValue: "0x5bf4af1a651a2a74b36e6eb208481f94c69fc959f756223dfa49608061937585",
|
| 102 |
-
previousBlockHashValue: "0xe865e912b504572a4d80ad018e29797e3c11f00bf9ae2549548a25779c9d7e57",
|
| 103 |
-
l1InfoRootValue: "0x2b9484b83c6398033241865b015fb9430eb3e159182a6075d00c924845cc393e",
|
| 104 |
-
}
|
| 105 |
-
runMigrationTest(t, 22, m)
|
| 106 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,57 +0,0 @@
|
|
| 1 |
-
-- +migrate Up
|
| 2 |
-
|
| 3 |
-
CREATE TABLE IF NOT EXISTS state.blob_sequence
|
| 4 |
-
(
|
| 5 |
-
index BIGINT PRIMARY KEY,
|
| 6 |
-
coinbase VARCHAR,
|
| 7 |
-
final_acc_input_hash VARCHAR,
|
| 8 |
-
first_blob_sequenced BIGINT,
|
| 9 |
-
last_blob_sequenced BIGINT,
|
| 10 |
-
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 11 |
-
received_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 12 |
-
block_num BIGINT NOT NULL REFERENCES state.block (block_num) ON DELETE CASCADE
|
| 13 |
-
);
|
| 14 |
-
|
| 15 |
-
comment on column state.blob_sequence.index is 'It is the id of this sequence, this value is internal and incremental';
|
| 16 |
-
comment on column state.blob_sequence.block_num is 'L1 Block where appear this sequence';
|
| 17 |
-
comment on column state.blob_sequence.first_blob_sequenced is 'first (included) blob_inner_num of this sequence (state.blob_inner.blob_inner_num)';
|
| 18 |
-
comment on column state.blob_sequence.first_blob_sequenced is 'last (included) blob_inner_num of this sequence (state.blob_inner.blob_inner_num)';
|
| 19 |
-
comment on column state.blob_sequence.received_at is 'time when it was received in node';
|
| 20 |
-
comment on column state.blob_sequence.created_at is 'time when was created on L1 (L1block tstamp)';
|
| 21 |
-
|
| 22 |
-
CREATE TABLE IF NOT EXISTS state.blob_inner_in
|
| 23 |
-
(
|
| 24 |
-
blob_inner_num BIGINT PRIMARY KEY,
|
| 25 |
-
blob_sequence_index BIGINT NOT NULL REFERENCES state.blob_sequence (index) ON DELETE CASCADE,
|
| 26 |
-
blob_type VARCHAR,
|
| 27 |
-
max_sequence_timestamp TIMESTAMP WITH TIME ZONE,
|
| 28 |
-
zk_gas_limit BIGINT,
|
| 29 |
-
l1_info_tree_leaf_index BIGINT,
|
| 30 |
-
l1_info_tree_root VARCHAR,
|
| 31 |
-
blob_data_hash VARCHAR,
|
| 32 |
-
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 33 |
-
-- if blob_type== blob
|
| 34 |
-
blob_type_index BIGINT,
|
| 35 |
-
blob_type_z VARCHAR,
|
| 36 |
-
blob_type_y VARCHAR,
|
| 37 |
-
blob_type_commitment VARCHAR,
|
| 38 |
-
blob_type_proof VARCHAR
|
| 39 |
-
);
|
| 40 |
-
|
| 41 |
-
comment on column state.blob_inner_in.updated_at is 'the creation time is blob_sequence.created_at, this is the last time when was updated (tipically Now() )';
|
| 42 |
-
comment on column state.blob_inner_in.blob_type is 'call_data, blob or forced';
|
| 43 |
-
comment on column state.blob_inner_in.blob_data_hash is 'is the hash of the blobData';
|
| 44 |
-
|
| 45 |
-
CREATE TABLE IF NOT EXISTS state.incoming_batch
|
| 46 |
-
(
|
| 47 |
-
batch_num BIGINT PRIMARY KEY,
|
| 48 |
-
blob_inner_num BIGINT NOT NULL REFERENCES state.blob_inner_in (blob_inner_num) ON DELETE CASCADE,
|
| 49 |
-
data BYTEA,
|
| 50 |
-
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
| 51 |
-
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
| 52 |
-
);
|
| 53 |
-
|
| 54 |
-
-- +migrate Down
|
| 55 |
-
DROP TABLE IF EXISTS state.incoming_batch;
|
| 56 |
-
DROP TABLE IF EXISTS state.blob_inner_in;
|
| 57 |
-
DROP TABLE IF EXISTS state.blob_sequence;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2,7 +2,6 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"database/sql"
|
| 5 |
-
"errors"
|
| 6 |
"fmt"
|
| 7 |
"testing"
|
| 8 |
|
|
@@ -13,7 +12,6 @@
|
|
| 13 |
"github.com/jackc/pgx/v4"
|
| 14 |
"github.com/jackc/pgx/v4/stdlib"
|
| 15 |
migrate "github.com/rubenv/sql-migrate"
|
| 16 |
-
"github.com/stretchr/testify/assert"
|
| 17 |
"github.com/stretchr/testify/require"
|
| 18 |
)
|
| 19 |
|
|
@@ -33,36 +31,6 @@
|
|
| 33 |
})
|
| 34 |
}
|
| 35 |
|
| 36 |
-
type migrationBase struct {
|
| 37 |
-
newIndexes []string
|
| 38 |
-
newTables []tableMetadata
|
| 39 |
-
newColumns []columnMetadata
|
| 40 |
-
|
| 41 |
-
removedIndexes []string
|
| 42 |
-
removedTables []tableMetadata
|
| 43 |
-
removedColumns []columnMetadata
|
| 44 |
-
}
|
| 45 |
-
|
| 46 |
-
func (m migrationBase) AssertNewAndRemovedItemsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 47 |
-
assertIndexesNotExist(t, db, m.removedIndexes)
|
| 48 |
-
assertTablesNotExist(t, db, m.removedTables)
|
| 49 |
-
assertColumnsNotExist(t, db, m.removedColumns)
|
| 50 |
-
|
| 51 |
-
assertIndexesExist(t, db, m.newIndexes)
|
| 52 |
-
assertTablesExist(t, db, m.newTables)
|
| 53 |
-
assertColumnsExist(t, db, m.newColumns)
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
func (m migrationBase) AssertNewAndRemovedItemsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 57 |
-
assertIndexesExist(t, db, m.removedIndexes)
|
| 58 |
-
assertTablesExist(t, db, m.removedTables)
|
| 59 |
-
assertColumnsExist(t, db, m.removedColumns)
|
| 60 |
-
|
| 61 |
-
assertIndexesNotExist(t, db, m.newIndexes)
|
| 62 |
-
assertTablesNotExist(t, db, m.newTables)
|
| 63 |
-
assertColumnsNotExist(t, db, m.newColumns)
|
| 64 |
-
}
|
| 65 |
-
|
| 66 |
type migrationTester interface {
|
| 67 |
// InsertData used to insert data in the affected tables of the migration that is being tested
|
| 68 |
// data will be inserted with the schema as it was previous the migration that is being tested
|
|
@@ -75,14 +43,6 @@
|
|
| 75 |
RunAssertsAfterMigrationDown(*testing.T, *sql.DB)
|
| 76 |
}
|
| 77 |
|
| 78 |
-
type tableMetadata struct {
|
| 79 |
-
schema, name string
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
type columnMetadata struct {
|
| 83 |
-
schema, tableName, name string
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
var (
|
| 87 |
stateDBCfg = dbutils.NewStateConfigFromEnv()
|
| 88 |
packrMigrations = map[string]*packr.Box{
|
|
@@ -156,122 +116,3 @@
|
|
| 156 |
}
|
| 157 |
return nil
|
| 158 |
}
|
| 159 |
-
|
| 160 |
-
func checkColumnExists(db *sql.DB, column columnMetadata) (bool, error) {
|
| 161 |
-
const getColumn = `SELECT count(*) FROM information_schema.columns WHERE table_schema=$1 AND table_name=$2 AND column_name=$3`
|
| 162 |
-
var result int
|
| 163 |
-
|
| 164 |
-
row := db.QueryRow(getColumn, column.schema, column.tableName, column.name)
|
| 165 |
-
err := row.Scan(&result)
|
| 166 |
-
|
| 167 |
-
if errors.Is(err, pgx.ErrNoRows) {
|
| 168 |
-
return false, nil
|
| 169 |
-
} else if err != nil {
|
| 170 |
-
return false, err
|
| 171 |
-
}
|
| 172 |
-
|
| 173 |
-
return (result == 1), nil
|
| 174 |
-
}
|
| 175 |
-
|
| 176 |
-
func assertColumnExists(t *testing.T, db *sql.DB, column columnMetadata) {
|
| 177 |
-
exists, err := checkColumnExists(db, column)
|
| 178 |
-
assert.NoError(t, err)
|
| 179 |
-
assert.True(t, exists)
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
-
func assertColumnNotExists(t *testing.T, db *sql.DB, column columnMetadata) {
|
| 183 |
-
exists, err := checkColumnExists(db, column)
|
| 184 |
-
assert.NoError(t, err)
|
| 185 |
-
assert.False(t, exists)
|
| 186 |
-
}
|
| 187 |
-
|
| 188 |
-
func assertColumnsExist(t *testing.T, db *sql.DB, columns []columnMetadata) {
|
| 189 |
-
for _, column := range columns {
|
| 190 |
-
assertColumnExists(t, db, column)
|
| 191 |
-
}
|
| 192 |
-
}
|
| 193 |
-
|
| 194 |
-
func assertColumnsNotExist(t *testing.T, db *sql.DB, columns []columnMetadata) {
|
| 195 |
-
for _, column := range columns {
|
| 196 |
-
assertColumnNotExists(t, db, column)
|
| 197 |
-
}
|
| 198 |
-
}
|
| 199 |
-
|
| 200 |
-
func checkTableExists(db *sql.DB, table tableMetadata) (bool, error) {
|
| 201 |
-
const getTable = `SELECT count(*) FROM information_schema.tables WHERE table_schema=$1 AND table_name=$2`
|
| 202 |
-
var result int
|
| 203 |
-
|
| 204 |
-
row := db.QueryRow(getTable, table.schema, table.name)
|
| 205 |
-
err := row.Scan(&result)
|
| 206 |
-
|
| 207 |
-
if errors.Is(err, pgx.ErrNoRows) {
|
| 208 |
-
return false, nil
|
| 209 |
-
} else if err != nil {
|
| 210 |
-
return false, err
|
| 211 |
-
}
|
| 212 |
-
|
| 213 |
-
return (result == 1), nil
|
| 214 |
-
}
|
| 215 |
-
|
| 216 |
-
func assertTableExists(t *testing.T, db *sql.DB, table tableMetadata) {
|
| 217 |
-
exists, err := checkTableExists(db, table)
|
| 218 |
-
assert.NoError(t, err)
|
| 219 |
-
assert.True(t, exists)
|
| 220 |
-
}
|
| 221 |
-
|
| 222 |
-
func assertTableNotExists(t *testing.T, db *sql.DB, table tableMetadata) {
|
| 223 |
-
exists, err := checkTableExists(db, table)
|
| 224 |
-
assert.NoError(t, err)
|
| 225 |
-
assert.False(t, exists)
|
| 226 |
-
}
|
| 227 |
-
|
| 228 |
-
func assertTablesExist(t *testing.T, db *sql.DB, tables []tableMetadata) {
|
| 229 |
-
for _, table := range tables {
|
| 230 |
-
assertTableExists(t, db, table)
|
| 231 |
-
}
|
| 232 |
-
}
|
| 233 |
-
|
| 234 |
-
func assertTablesNotExist(t *testing.T, db *sql.DB, tables []tableMetadata) {
|
| 235 |
-
for _, table := range tables {
|
| 236 |
-
assertTableNotExists(t, db, table)
|
| 237 |
-
}
|
| 238 |
-
}
|
| 239 |
-
|
| 240 |
-
func checkIndexExists(db *sql.DB, index string) (bool, error) {
|
| 241 |
-
const getIndex = `SELECT count(*) FROM pg_indexes WHERE indexname = $1;`
|
| 242 |
-
row := db.QueryRow(getIndex, index)
|
| 243 |
-
|
| 244 |
-
var result int
|
| 245 |
-
err := row.Scan(&result)
|
| 246 |
-
if errors.Is(err, pgx.ErrNoRows) {
|
| 247 |
-
return false, nil
|
| 248 |
-
} else if err != nil {
|
| 249 |
-
return false, err
|
| 250 |
-
}
|
| 251 |
-
|
| 252 |
-
return (result == 1), nil
|
| 253 |
-
}
|
| 254 |
-
|
| 255 |
-
func assertIndexExists(t *testing.T, db *sql.DB, index string) {
|
| 256 |
-
exists, err := checkIndexExists(db, index)
|
| 257 |
-
assert.NoError(t, err)
|
| 258 |
-
assert.True(t, exists)
|
| 259 |
-
}
|
| 260 |
-
|
| 261 |
-
func assertIndexNotExists(t *testing.T, db *sql.DB, index string) {
|
| 262 |
-
exists, err := checkIndexExists(db, index)
|
| 263 |
-
assert.NoError(t, err)
|
| 264 |
-
assert.False(t, exists)
|
| 265 |
-
}
|
| 266 |
-
|
| 267 |
-
func assertIndexesExist(t *testing.T, db *sql.DB, indexes []string) {
|
| 268 |
-
for _, index := range indexes {
|
| 269 |
-
assertIndexExists(t, db, index)
|
| 270 |
-
}
|
| 271 |
-
}
|
| 272 |
-
|
| 273 |
-
func assertIndexesNotExist(t *testing.T, db *sql.DB, indexes []string) {
|
| 274 |
-
for _, index := range indexes {
|
| 275 |
-
assertIndexNotExists(t, db, index)
|
| 276 |
-
}
|
| 277 |
-
}
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"database/sql"
|
|
|
|
| 5 |
"fmt"
|
| 6 |
"testing"
|
| 7 |
|
|
|
|
| 12 |
"github.com/jackc/pgx/v4"
|
| 13 |
"github.com/jackc/pgx/v4/stdlib"
|
| 14 |
migrate "github.com/rubenv/sql-migrate"
|
|
|
|
| 15 |
"github.com/stretchr/testify/require"
|
| 16 |
)
|
| 17 |
|
|
|
|
| 31 |
})
|
| 32 |
}
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
type migrationTester interface {
|
| 35 |
// InsertData used to insert data in the affected tables of the migration that is being tested
|
| 36 |
// data will be inserted with the schema as it was previous the migration that is being tested
|
|
|
|
| 43 |
RunAssertsAfterMigrationDown(*testing.T, *sql.DB)
|
| 44 |
}
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
var (
|
| 47 |
stateDBCfg = dbutils.NewStateConfigFromEnv()
|
| 48 |
packrMigrations = map[string]*packr.Box{
|
|
|
|
| 116 |
}
|
| 117 |
return nil
|
| 118 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- +migrate Up
|
| 2 |
+
|
| 3 |
+
CREATE TABLE IF NOT EXISTS state.batch_data_backup
|
| 4 |
+
(
|
| 5 |
+
batch_num BIGINT,
|
| 6 |
+
data BYTEA,
|
| 7 |
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 8 |
+
PRIMARY KEY (batch_num, created_at)
|
| 9 |
+
);
|
| 10 |
+
|
| 11 |
+
-- +migrate StatementBegin
|
| 12 |
+
CREATE OR REPLACE FUNCTION backup_batch() RETURNS trigger AS $$
|
| 13 |
+
BEGIN
|
| 14 |
+
INSERT INTO state.batch_data_backup (batch_num, data)
|
| 15 |
+
VALUES (OLD.batch_num, OLD.raw_txs_data)
|
| 16 |
+
ON CONFLICT (batch_num, created_at) DO UPDATE SET
|
| 17 |
+
data = EXCLUDED.data;
|
| 18 |
+
RETURN OLD;
|
| 19 |
+
END;
|
| 20 |
+
$$
|
| 21 |
+
LANGUAGE plpgsql;
|
| 22 |
+
-- +migrate StatementEnd
|
| 23 |
+
|
| 24 |
+
CREATE TRIGGER backup_batch
|
| 25 |
+
BEFORE DELETE ON state.batch FOR EACH ROW
|
| 26 |
+
EXECUTE PROCEDURE backup_batch();
|
| 27 |
+
|
| 28 |
+
-- +migrate Down
|
| 29 |
+
|
| 30 |
+
DROP TRIGGER IF EXISTS backup_batch ON state.batch;
|
| 31 |
+
DROP FUNCTION IF EXISTS backup_batch();
|
| 32 |
+
DROP TABLE IF EXISTS state.batch_data_backup;
|
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
PATH_TO_ZKEVM_NODE_REPO="/home/stefan/go/src/Polygon/zkevm-node/"
|
| 2 |
+
diff -ruN \
|
| 3 |
+
-I ".*github.com\/0x.*" \
|
| 4 |
+
-x "*mock*" -x ".git" \
|
| 5 |
+
-x ".github" \
|
| 6 |
+
-x ".gitignore" \
|
| 7 |
+
-x ".vscode" \
|
| 8 |
+
-x "ci" \
|
| 9 |
+
-x "environments" \
|
| 10 |
+
-x "*.md" \
|
| 11 |
+
-x "*.html" \
|
| 12 |
+
-x "*.html" \
|
| 13 |
+
-x "*.json" \
|
| 14 |
+
-x "*.toml" \
|
| 15 |
+
-x "*.abi" \
|
| 16 |
+
-x "*.bin" \
|
| 17 |
+
-x "*.pb.go" \
|
| 18 |
+
-x "smartcontracts" \
|
| 19 |
+
-x "go.sum" \
|
| 20 |
+
-x "mock*.go" \
|
| 21 |
+
-x "*venv*" \
|
| 22 |
+
-x "/dist/" \
|
| 23 |
+
-x "/test/e2e/keystore" \
|
| 24 |
+
-x "/test/vectors/src/**/*md" \
|
| 25 |
+
-x "/test/vectors/src/**/*js" \
|
| 26 |
+
-x "/test/vectors/src/**/*sol" \
|
| 27 |
+
-x "/test/vectors/src/**/*sh" \
|
| 28 |
+
-x "/test/vectors/src/package.json" \
|
| 29 |
+
-x "/test/contracts/bin/**/*.bin" \
|
| 30 |
+
-x "/test/contracts/bin/**/*.abi" \
|
| 31 |
+
-x "/tools/datastreamer/*.bin" \
|
| 32 |
+
-x "/test/datastreamer/*.db/*" \
|
| 33 |
+
-x "/test/*.bin" \
|
| 34 |
+
-x "/test/*.db/*" \
|
| 35 |
+
-x "**/.DS_Store" \
|
| 36 |
+
-x ".vscode" \
|
| 37 |
+
-x ".idea/" \
|
| 38 |
+
-x ".env" \
|
| 39 |
+
-x "out.dat" \
|
| 40 |
+
-x "cmd/__debug_bin" \
|
| 41 |
+
-x ".venv" \
|
| 42 |
+
-x "*metrics.txt" \
|
| 43 |
+
-x "coverage.out" \
|
| 44 |
+
-x "*datastream.db*" \
|
| 45 |
+
${PATH_TO_ZKEVM_NODE_REPO} . | \
|
| 46 |
+
diff2html -i stdin -s side -t "zkEVM node vs CDK validium node</br><h2>zkevm-node version: v0.6.0<h2/>" \
|
| 47 |
+
-F ./docs/diff/diff.html
|
|
@@ -107,7 +107,7 @@
|
|
| 107 |
zkevm-prover:
|
| 108 |
container_name: zkevm-prover
|
| 109 |
restart: unless-stopped
|
| 110 |
-
image: hermeznetwork/zkevm-prover:v6.0.
|
| 111 |
depends_on:
|
| 112 |
zkevm-state-db:
|
| 113 |
condition: service_healthy
|
|
|
|
| 107 |
zkevm-prover:
|
| 108 |
container_name: zkevm-prover
|
| 109 |
restart: unless-stopped
|
| 110 |
+
image: hermeznetwork/zkevm-prover:v6.0.0
|
| 111 |
depends_on:
|
| 112 |
zkevm-state-db:
|
| 113 |
condition: service_healthy
|
|
@@ -14,7 +14,6 @@
|
|
| 14 |
# CONTAINER FOR RUNNING BINARY
|
| 15 |
FROM alpine:3.18
|
| 16 |
COPY --from=build /src/dist/zkevm-node /app/zkevm-node
|
| 17 |
-
COPY --from=build /src/config/environments/testnet/node.config.toml /app/example.config.toml
|
| 18 |
RUN apk update && apk add postgresql15-client
|
| 19 |
EXPOSE 8123
|
| 20 |
CMD ["/bin/sh", "-c", "/app/zkevm-node run"]
|
|
|
|
| 14 |
# CONTAINER FOR RUNNING BINARY
|
| 15 |
FROM alpine:3.18
|
| 16 |
COPY --from=build /src/dist/zkevm-node /app/zkevm-node
|
|
|
|
| 17 |
RUN apk update && apk add postgresql15-client
|
| 18 |
EXPOSE 8123
|
| 19 |
CMD ["/bin/sh", "-c", "/app/zkevm-node run"]
|
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM alpine:3.18
|
| 2 |
+
|
| 3 |
+
COPY zkevm-node /app/zkevm-node
|
| 4 |
+
|
| 5 |
+
EXPOSE 8123
|
| 6 |
+
|
| 7 |
+
RUN addgroup -S zkevm-group \
|
| 8 |
+
&& adduser -S zkevm-user -G zkevm-group
|
| 9 |
+
|
| 10 |
+
RUN chown -R zkevm-user:zkevm-group /app
|
| 11 |
+
|
| 12 |
+
USER zkevm-user
|
| 13 |
+
|
| 14 |
+
CMD ["/app/zkevm-node"]
|
| 15 |
+
|
|
@@ -6,8 +6,6 @@
|
|
| 6 |
type Config struct {
|
| 7 |
// URL is the URL of the Ethereum node for L1
|
| 8 |
URL string `mapstructure:"URL"`
|
| 9 |
-
// ConsensusL1URL is the URL of the consensus L1 RPC endpoint
|
| 10 |
-
ConsensusL1URL string `mapstructure:"ConsensusL1URL"`
|
| 11 |
|
| 12 |
// ForkIDChunkSize is the max interval for each call to L1 provider to get the forkIDs
|
| 13 |
ForkIDChunkSize uint64 `mapstructure:"ForkIDChunkSize"`
|
|
|
|
| 6 |
type Config struct {
|
| 7 |
// URL is the URL of the Ethereum node for L1
|
| 8 |
URL string `mapstructure:"URL"`
|
|
|
|
|
|
|
| 9 |
|
| 10 |
// ForkIDChunkSize is the max interval for each call to L1 provider to get the forkIDs
|
| 11 |
ForkIDChunkSize uint64 `mapstructure:"ForkIDChunkSize"`
|
|
@@ -1,86 +0,0 @@
|
|
| 1 |
-
package eip4844
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
|
| 7 |
-
beaconclient "github.com/0xPolygonHermez/zkevm-node/beacon_client"
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
-
)
|
| 10 |
-
|
| 11 |
-
// EthermanEIP4844 represents the EIP-4844 implementation
|
| 12 |
-
type EthermanEIP4844 struct {
|
| 13 |
-
beaconClient *beaconclient.BeaconAPIClient
|
| 14 |
-
initialized bool
|
| 15 |
-
genesisTime uint64
|
| 16 |
-
secondsPerSlot uint64
|
| 17 |
-
}
|
| 18 |
-
|
| 19 |
-
// NewEthermanEIP4844 creates a new EthermanEIP4844
|
| 20 |
-
func NewEthermanEIP4844(beaconClient *beaconclient.BeaconAPIClient) *EthermanEIP4844 {
|
| 21 |
-
return &EthermanEIP4844{
|
| 22 |
-
beaconClient: beaconClient,
|
| 23 |
-
initialized: false,
|
| 24 |
-
}
|
| 25 |
-
}
|
| 26 |
-
|
| 27 |
-
// IsInitialized returns if the EthermanEIP4844 is initialized
|
| 28 |
-
func (e *EthermanEIP4844) IsInitialized() bool {
|
| 29 |
-
return e.initialized && e.genesisTime != 0 && e.secondsPerSlot != 0
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
// Initialize initializes the EthermanEIP4844
|
| 33 |
-
func (e *EthermanEIP4844) Initialize(ctx context.Context) error {
|
| 34 |
-
// You can initialize multiples times and will fetch again the data
|
| 35 |
-
|
| 36 |
-
configSpec, err := e.beaconClient.ConfigSpec(ctx)
|
| 37 |
-
if err != nil {
|
| 38 |
-
return fmt.Errorf("error fetching config spec: %v", err)
|
| 39 |
-
}
|
| 40 |
-
|
| 41 |
-
e.secondsPerSlot = configSpec.SecondsPerSlot
|
| 42 |
-
|
| 43 |
-
genesis, err := e.beaconClient.BeaconGenesis(ctx)
|
| 44 |
-
if err != nil {
|
| 45 |
-
return fmt.Errorf("error fetching beacon genesis: %v", err)
|
| 46 |
-
}
|
| 47 |
-
e.genesisTime = genesis.GenesisTime
|
| 48 |
-
if e.secondsPerSlot == 0 || e.genesisTime == 0 {
|
| 49 |
-
return fmt.Errorf("genesisTime:%d or secondsPerSlot: %d is 0", e.genesisTime, e.secondsPerSlot)
|
| 50 |
-
}
|
| 51 |
-
e.initialized = true
|
| 52 |
-
|
| 53 |
-
return nil
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
// GetBlobSidecar returns the blob sidecar for a given blockTime and kzgCommitment
|
| 57 |
-
func (e *EthermanEIP4844) GetBlobSidecar(ctx context.Context, blockTime uint64, kzgCommitment string) ([]byte, error) {
|
| 58 |
-
slot, err := e.CalculateSlot(blockTime)
|
| 59 |
-
if err != nil {
|
| 60 |
-
errComposed := fmt.Errorf("error calculating Slot blob sidecars: %v", err)
|
| 61 |
-
log.Error(errComposed.Error())
|
| 62 |
-
return nil, errComposed
|
| 63 |
-
}
|
| 64 |
-
sidecars, err := e.beaconClient.BeaconBlobSidecars(ctx, slot)
|
| 65 |
-
if err != nil {
|
| 66 |
-
errComposed := fmt.Errorf("error fetching beacon blob sidecars: %v", err)
|
| 67 |
-
log.Error(errComposed.Error())
|
| 68 |
-
return nil, errComposed
|
| 69 |
-
}
|
| 70 |
-
for _, sidecar := range sidecars.Sidecars {
|
| 71 |
-
if sidecar.KzgCommitment == kzgCommitment {
|
| 72 |
-
return sidecar.Blob, nil
|
| 73 |
-
}
|
| 74 |
-
}
|
| 75 |
-
err = fmt.Errorf("sidecar not found")
|
| 76 |
-
log.Error(err.Error())
|
| 77 |
-
return nil, err
|
| 78 |
-
}
|
| 79 |
-
|
| 80 |
-
// CalculateSlot calculates the slot for a given blockTime
|
| 81 |
-
func (e *EthermanEIP4844) CalculateSlot(blockTime uint64) (uint64, error) {
|
| 82 |
-
if !e.IsInitialized() {
|
| 83 |
-
return 0, fmt.Errorf("EIP-4844 not initialized,please call Initialize(..) function first")
|
| 84 |
-
}
|
| 85 |
-
return (blockTime - e.genesisTime) / e.secondsPerSlot, nil
|
| 86 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -3,6 +3,7 @@
|
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
"context"
|
|
|
|
| 6 |
"encoding/json"
|
| 7 |
"errors"
|
| 8 |
"fmt"
|
|
@@ -43,13 +44,8 @@
|
|
| 43 |
"golang.org/x/crypto/sha3"
|
| 44 |
)
|
| 45 |
|
| 46 |
-
const (
|
| 47 |
-
// ETrogUpgradeVersion is the version of the LxLy upgrade
|
| 48 |
-
ETrogUpgradeVersion = 2
|
| 49 |
-
)
|
| 50 |
-
|
| 51 |
var (
|
| 52 |
-
// Events
|
| 53 |
setBatchFeeSignatureHash = crypto.Keccak256Hash([]byte("SetBatchFee(uint256)"))
|
| 54 |
setTrustedAggregatorSignatureHash = crypto.Keccak256Hash([]byte("SetTrustedAggregator(address)")) // Used in oldZkEvm as well
|
| 55 |
setVerifyBatchTimeTargetSignatureHash = crypto.Keccak256Hash([]byte("SetVerifyBatchTimeTarget(uint64)")) // Used in oldZkEvm as well
|
|
@@ -94,13 +90,13 @@
|
|
| 94 |
updateL1InfoTreeSignatureHash = crypto.Keccak256Hash([]byte("UpdateL1InfoTree(bytes32,bytes32)"))
|
| 95 |
|
| 96 |
// PreLxLy events
|
| 97 |
-
updateGlobalExitRootSignatureHash
|
| 98 |
-
|
| 99 |
-
transferOwnershipSignatureHash
|
| 100 |
-
updateZkEVMVersionSignatureHash
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
sequenceBatchesPreEtrogSignatureHash
|
| 104 |
|
| 105 |
// Proxy events
|
| 106 |
initializedProxySignatureHash = crypto.Keccak256Hash([]byte("Initialized(uint8)"))
|
|
@@ -113,6 +109,11 @@
|
|
| 113 |
// methodIDSequenceBatchesElderberry: MethodID for sequenceBatches in Elderberry
|
| 114 |
methodIDSequenceBatchesElderberry = []byte{0xde, 0xf5, 0x7e, 0x54} // 0xdef57e54 sequenceBatches((bytes,bytes32,uint64,bytes32)[],uint64,uint64,address)
|
| 115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
// ErrNotFound is used when the object is not found
|
| 117 |
ErrNotFound = errors.New("not found")
|
| 118 |
// ErrIsReadOnlyMode is used when the EtherMan client is in read-only mode.
|
|
@@ -163,7 +164,6 @@
|
|
| 163 |
ethereum.LogFilterer
|
| 164 |
ethereum.TransactionReader
|
| 165 |
ethereum.TransactionSender
|
| 166 |
-
ethereum.PendingStateReader
|
| 167 |
|
| 168 |
bind.DeployBackend
|
| 169 |
}
|
|
@@ -189,78 +189,66 @@
|
|
| 189 |
|
| 190 |
// Client is a simple implementation of EtherMan.
|
| 191 |
type Client struct {
|
| 192 |
-
EthClient
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
SCAddresses
|
| 202 |
|
| 203 |
RollupID uint32
|
| 204 |
|
| 205 |
GasProviders externalGasProviders
|
| 206 |
|
| 207 |
-
l1Cfg
|
| 208 |
-
cfg
|
| 209 |
-
auth
|
| 210 |
-
|
| 211 |
-
|
|
|
|
| 212 |
}
|
| 213 |
|
| 214 |
// NewClient creates a new etherman.
|
| 215 |
-
func NewClient(cfg Config, l1Config L1Config) (*Client, error) {
|
| 216 |
// Connect to ethereum node
|
| 217 |
ethClient, err := ethclient.Dial(cfg.URL)
|
| 218 |
if err != nil {
|
| 219 |
log.Errorf("error connecting to %s: %+v", cfg.URL, err)
|
| 220 |
return nil, err
|
| 221 |
}
|
| 222 |
-
if cfg.ConsensusL1URL == "" {
|
| 223 |
-
log.Warn("ConsensusL1URL is not set, so Feijoa is not going to work")
|
| 224 |
-
}
|
| 225 |
-
feijoaEnabled := true
|
| 226 |
-
beaconClient := beaconclient.NewBeaconAPIClient(cfg.ConsensusL1URL)
|
| 227 |
-
eip4844 := eip4844.NewEthermanEIP4844(beaconClient)
|
| 228 |
-
if err := eip4844.Initialize(context.Background()); err != nil {
|
| 229 |
-
// TODO: Must be mandatory to have a consensusL1URL configured, but
|
| 230 |
-
// for maintain compatibility allow to disable Feijoa
|
| 231 |
-
// so the log.Warnf must be an Errorf and must return nil, err
|
| 232 |
-
log.Warnf("error initializing EIP-4844,Feijoa is going to be disabled. URL:%s : %+v", cfg.ConsensusL1URL, err)
|
| 233 |
-
feijoaEnabled = false
|
| 234 |
-
}
|
| 235 |
// Create smc clients
|
| 236 |
-
|
| 237 |
if err != nil {
|
| 238 |
log.Errorf("error creating Polygonzkevm client (%s). Error: %w", l1Config.ZkEVMAddr.String(), err)
|
| 239 |
return nil, err
|
| 240 |
}
|
| 241 |
-
|
| 242 |
if err != nil {
|
| 243 |
-
log.Errorf("error creating
|
| 244 |
return nil, err
|
| 245 |
}
|
| 246 |
-
|
| 247 |
if err != nil {
|
| 248 |
-
log.Errorf("error creating
|
| 249 |
return nil, err
|
| 250 |
}
|
| 251 |
-
|
| 252 |
if err != nil {
|
| 253 |
log.Errorf("error creating NewPolygonrollupmanager client (%s). Error: %w", l1Config.RollupManagerAddr.String(), err)
|
| 254 |
return nil, err
|
| 255 |
}
|
| 256 |
-
|
| 257 |
if err != nil {
|
| 258 |
log.Errorf("error creating NewPolygonzkevmglobalexitroot client (%s). Error: %w", l1Config.GlobalExitRootManagerAddr.String(), err)
|
| 259 |
return nil, err
|
| 260 |
}
|
| 261 |
-
|
| 262 |
if err != nil {
|
| 263 |
-
log.Errorf("error creating
|
| 264 |
return nil, err
|
| 265 |
}
|
| 266 |
pol, err := pol.NewPol(l1Config.PolAddr, ethClient)
|
|
@@ -268,12 +256,15 @@
|
|
| 268 |
log.Errorf("error creating NewPol client (%s). Error: %w", l1Config.PolAddr.String(), err)
|
| 269 |
return nil, err
|
| 270 |
}
|
| 271 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
if err != nil {
|
| 273 |
-
log.Errorf("error creating NewFeijoaContracts client (%s). Error: %w", l1Config.RollupManagerAddr.String(), err)
|
| 274 |
return nil, err
|
| 275 |
}
|
| 276 |
-
scAddresses
|
| 277 |
scAddresses = append(scAddresses, l1Config.ZkEVMAddr, l1Config.RollupManagerAddr, l1Config.GlobalExitRootManagerAddr)
|
| 278 |
|
| 279 |
gProviders := []ethereum.GasPricer{ethClient}
|
|
@@ -288,43 +279,40 @@
|
|
| 288 |
}
|
| 289 |
metrics.Register()
|
| 290 |
// Get RollupID
|
| 291 |
-
rollupID, err :=
|
| 292 |
if err != nil {
|
| 293 |
log.Debugf("error rollupManager.RollupAddressToID(%s). Error: %w", l1Config.RollupManagerAddr, err)
|
| 294 |
return nil, err
|
| 295 |
}
|
| 296 |
log.Debug("rollupID: ", rollupID)
|
| 297 |
|
| 298 |
-
|
| 299 |
-
EthClient:
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
Pol:
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
|
|
|
| 309 |
GasProviders: externalGasProviders{
|
| 310 |
MultiGasProvider: cfg.MultiGasProvider,
|
| 311 |
Providers: gProviders,
|
| 312 |
},
|
| 313 |
-
l1Cfg:
|
| 314 |
-
cfg:
|
| 315 |
-
auth:
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
eventFeijoaManager := NewEventManager(client, NewCallDataExtratorGeth(ethClient))
|
| 320 |
-
eventFeijoaManager.AddProcessor(NewEventFeijoaSequenceBlobsProcessor(feijoaContracts))
|
| 321 |
-
client.eventFeijoaManager = eventFeijoaManager
|
| 322 |
-
}
|
| 323 |
-
return client, nil
|
| 324 |
}
|
| 325 |
|
| 326 |
// VerifyGenBlockNumber verifies if the genesis Block Number is valid
|
| 327 |
func (etherMan *Client) VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error) {
|
|
|
|
| 328 |
start := time.Now()
|
| 329 |
log.Info("Verifying genesis blockNumber: ", genBlockNumber)
|
| 330 |
// Filter query
|
|
@@ -342,11 +330,11 @@
|
|
| 342 |
if len(logs) == 0 {
|
| 343 |
return false, fmt.Errorf("the specified genBlockNumber in config file does not contain any forkID event. Please use the proper blockNumber.")
|
| 344 |
}
|
| 345 |
-
var zkevmVersion
|
| 346 |
switch logs[0].Topics[0] {
|
| 347 |
case updateZkEVMVersionSignatureHash:
|
| 348 |
log.Debug("UpdateZkEVMVersion event detected during the Verification of the GenBlockNumber")
|
| 349 |
-
zkevmV, err := etherMan.
|
| 350 |
if err != nil {
|
| 351 |
return false, err
|
| 352 |
}
|
|
@@ -355,12 +343,12 @@
|
|
| 355 |
}
|
| 356 |
case createNewRollupSignatureHash:
|
| 357 |
log.Debug("CreateNewRollup event detected during the Verification of the GenBlockNumber")
|
| 358 |
-
createNewRollupEvent, err := etherMan.
|
| 359 |
if err != nil {
|
| 360 |
return false, err
|
| 361 |
}
|
| 362 |
// Query to get the forkID
|
| 363 |
-
rollupType, err := etherMan.
|
| 364 |
if err != nil {
|
| 365 |
log.Error(err)
|
| 366 |
return false, err
|
|
@@ -375,36 +363,16 @@
|
|
| 375 |
return true, nil
|
| 376 |
}
|
| 377 |
|
| 378 |
-
// GetL1BlockUpgradeLxLy It returns the block genesis for LxLy before genesisBlock or error
|
| 379 |
-
// TODO: Check if all RPC providers support this range of blocks
|
| 380 |
-
func (etherMan *Client) GetL1BlockUpgradeLxLy(ctx context.Context, genesisBlock uint64) (uint64, error) {
|
| 381 |
-
it, err := etherMan.EtrogRollupManager.FilterInitialized(&bind.FilterOpts{
|
| 382 |
-
Start: 1,
|
| 383 |
-
End: &genesisBlock,
|
| 384 |
-
Context: ctx,
|
| 385 |
-
})
|
| 386 |
-
if err != nil {
|
| 387 |
-
return uint64(0), err
|
| 388 |
-
}
|
| 389 |
-
for it.Next() {
|
| 390 |
-
log.Debugf("BlockNumber: %d Topics:Initialized(%d)", it.Event.Raw.BlockNumber, it.Event.Version)
|
| 391 |
-
if it.Event.Version == ETrogUpgradeVersion { // 2 is ETROG (LxLy upgrade)
|
| 392 |
-
log.Infof("LxLy upgrade found at blockNumber: %d", it.Event.Raw.BlockNumber)
|
| 393 |
-
return it.Event.Raw.BlockNumber, nil
|
| 394 |
-
}
|
| 395 |
-
}
|
| 396 |
-
return uint64(0), ErrNotFound
|
| 397 |
-
}
|
| 398 |
-
|
| 399 |
// GetForks returns fork information
|
| 400 |
func (etherMan *Client) GetForks(ctx context.Context, genBlockNumber uint64, lastL1BlockSynced uint64) ([]state.ForkIDInterval, error) {
|
| 401 |
log.Debug("Getting forkIDs from blockNumber: ", genBlockNumber)
|
| 402 |
start := time.Now()
|
| 403 |
var logs []types.Log
|
| 404 |
-
|
| 405 |
if lastL1BlockSynced < genBlockNumber {
|
| 406 |
lastL1BlockSynced = genBlockNumber
|
| 407 |
}
|
|
|
|
| 408 |
log.Debug("Using ForkIDChunkSize: ", etherMan.cfg.ForkIDChunkSize)
|
| 409 |
for i := genBlockNumber; i <= lastL1BlockSynced; i = i + etherMan.cfg.ForkIDChunkSize + 1 {
|
| 410 |
final := i + etherMan.cfg.ForkIDChunkSize
|
|
@@ -429,11 +397,11 @@
|
|
| 429 |
|
| 430 |
var forks []state.ForkIDInterval
|
| 431 |
for i, l := range logs {
|
| 432 |
-
var zkevmVersion
|
| 433 |
switch l.Topics[0] {
|
| 434 |
case updateZkEVMVersionSignatureHash:
|
| 435 |
log.Debug("updateZkEVMVersion Event received")
|
| 436 |
-
zkevmV, err := etherMan.
|
| 437 |
if err != nil {
|
| 438 |
return []state.ForkIDInterval{}, err
|
| 439 |
}
|
|
@@ -442,7 +410,7 @@
|
|
| 442 |
}
|
| 443 |
case updateRollupSignatureHash:
|
| 444 |
log.Debug("updateRollup Event received")
|
| 445 |
-
updateRollupEvent, err := etherMan.
|
| 446 |
if err != nil {
|
| 447 |
return []state.ForkIDInterval{}, err
|
| 448 |
}
|
|
@@ -450,7 +418,7 @@
|
|
| 450 |
continue
|
| 451 |
}
|
| 452 |
// Query to get the forkID
|
| 453 |
-
rollupType, err := etherMan.
|
| 454 |
if err != nil {
|
| 455 |
return []state.ForkIDInterval{}, err
|
| 456 |
}
|
|
@@ -459,7 +427,7 @@
|
|
| 459 |
|
| 460 |
case addExistingRollupSignatureHash:
|
| 461 |
log.Debug("addExistingRollup Event received")
|
| 462 |
-
addExistingRollupEvent, err := etherMan.
|
| 463 |
if err != nil {
|
| 464 |
return []state.ForkIDInterval{}, err
|
| 465 |
}
|
|
@@ -471,7 +439,7 @@
|
|
| 471 |
|
| 472 |
case createNewRollupSignatureHash:
|
| 473 |
log.Debug("createNewRollup Event received")
|
| 474 |
-
createNewRollupEvent, err := etherMan.
|
| 475 |
if err != nil {
|
| 476 |
return []state.ForkIDInterval{}, err
|
| 477 |
}
|
|
@@ -479,7 +447,7 @@
|
|
| 479 |
continue
|
| 480 |
}
|
| 481 |
// Query to get the forkID
|
| 482 |
-
rollupType, err := etherMan.
|
| 483 |
if err != nil {
|
| 484 |
log.Error(err)
|
| 485 |
return []state.ForkIDInterval{}, err
|
|
@@ -531,25 +499,6 @@
|
|
| 531 |
return blocks, blocksOrder, nil
|
| 532 |
}
|
| 533 |
|
| 534 |
-
// GetRollupInfoByBlockRangePreviousRollupGenesis function retrieves the Rollup information that are included in all this ethereum blocks
|
| 535 |
-
// but it only retrieves the information from the previous rollup genesis block to the current block.
|
| 536 |
-
func (etherMan *Client) GetRollupInfoByBlockRangePreviousRollupGenesis(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]Block, map[common.Hash][]Order, error) {
|
| 537 |
-
// Filter query
|
| 538 |
-
query := ethereum.FilterQuery{
|
| 539 |
-
FromBlock: new(big.Int).SetUint64(fromBlock),
|
| 540 |
-
Addresses: []common.Address{etherMan.l1Cfg.GlobalExitRootManagerAddr},
|
| 541 |
-
Topics: [][]common.Hash{{updateL1InfoTreeSignatureHash}},
|
| 542 |
-
}
|
| 543 |
-
if toBlock != nil {
|
| 544 |
-
query.ToBlock = new(big.Int).SetUint64(*toBlock)
|
| 545 |
-
}
|
| 546 |
-
blocks, blocksOrder, err := etherMan.readEvents(ctx, query)
|
| 547 |
-
if err != nil {
|
| 548 |
-
return nil, nil, err
|
| 549 |
-
}
|
| 550 |
-
return blocks, blocksOrder, nil
|
| 551 |
-
}
|
| 552 |
-
|
| 553 |
// Order contains the event order to let the synchronizer store the information following this order.
|
| 554 |
type Order struct {
|
| 555 |
Name EventOrder
|
|
@@ -580,17 +529,8 @@
|
|
| 580 |
metrics.ReadAndProcessAllEventsTime(time.Since(start))
|
| 581 |
return blocks, blocksOrder, nil
|
| 582 |
}
|
| 583 |
-
func (etherMan *Client) processEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 584 |
-
if etherMan.eventFeijoaManager != nil {
|
| 585 |
-
processed, err := etherMan.eventFeijoaManager.ProcessEvent(ctx, vLog, blocks, blocksOrder)
|
| 586 |
-
if processed || err != nil {
|
| 587 |
-
return err
|
| 588 |
-
}
|
| 589 |
-
}
|
| 590 |
-
return etherMan.processEventLegacy(ctx, vLog, blocks, blocksOrder)
|
| 591 |
-
}
|
| 592 |
|
| 593 |
-
func (etherMan *Client)
|
| 594 |
switch vLog.Topics[0] {
|
| 595 |
case sequenceBatchesSignatureHash:
|
| 596 |
return etherMan.sequencedBatchesEvent(ctx, vLog, blocks, blocksOrder)
|
|
@@ -612,8 +552,8 @@
|
|
| 612 |
case rollupManagerVerifyBatchesSignatureHash:
|
| 613 |
log.Debug("RollupManagerVerifyBatches event detected. Ignoring...")
|
| 614 |
return nil
|
| 615 |
-
case
|
| 616 |
-
return etherMan.
|
| 617 |
case verifyBatchesSignatureHash:
|
| 618 |
return etherMan.verifyBatchesEvent(ctx, vLog, blocks, blocksOrder)
|
| 619 |
case sequenceForceBatchesSignatureHash:
|
|
@@ -653,8 +593,8 @@
|
|
| 653 |
case consolidatePendingStateSignatureHash:
|
| 654 |
log.Debug("ConsolidatePendingState event detected. Ignoring...")
|
| 655 |
return nil
|
| 656 |
-
case
|
| 657 |
-
log.Debug("
|
| 658 |
return nil
|
| 659 |
case setTrustedAggregatorTimeoutSignatureHash:
|
| 660 |
log.Debug("SetTrustedAggregatorTimeout event detected. Ignoring...")
|
|
@@ -689,8 +629,8 @@
|
|
| 689 |
case overridePendingStateSignatureHash:
|
| 690 |
log.Debug("OverridePendingState event detected. Ignoring...")
|
| 691 |
return nil
|
| 692 |
-
case
|
| 693 |
-
log.Debug("
|
| 694 |
return nil
|
| 695 |
case roleAdminChangedSignatureHash:
|
| 696 |
log.Debug("RoleAdminChanged event detected. Ignoring...")
|
|
@@ -726,7 +666,7 @@
|
|
| 726 |
|
| 727 |
func (etherMan *Client) updateZkevmVersion(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 728 |
log.Debug("UpdateZkEVMVersion event detected")
|
| 729 |
-
zkevmVersion, err := etherMan.
|
| 730 |
if err != nil {
|
| 731 |
log.Error("error parsing UpdateZkEVMVersion event. Error: ", err)
|
| 732 |
return err
|
|
@@ -736,12 +676,12 @@
|
|
| 736 |
|
| 737 |
func (etherMan *Client) updateRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 738 |
log.Debug("UpdateRollup event detected")
|
| 739 |
-
updateRollup, err := etherMan.
|
| 740 |
if err != nil {
|
| 741 |
log.Error("error parsing UpdateRollup event. Error: ", err)
|
| 742 |
return err
|
| 743 |
}
|
| 744 |
-
rollupType, err := etherMan.
|
| 745 |
if err != nil {
|
| 746 |
return err
|
| 747 |
}
|
|
@@ -750,12 +690,12 @@
|
|
| 750 |
|
| 751 |
func (etherMan *Client) createNewRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 752 |
log.Debug("createNewRollup event detected")
|
| 753 |
-
createRollup, err := etherMan.
|
| 754 |
if err != nil {
|
| 755 |
log.Error("error parsing createNewRollup event. Error: ", err)
|
| 756 |
return err
|
| 757 |
}
|
| 758 |
-
rollupType, err := etherMan.
|
| 759 |
if err != nil {
|
| 760 |
return err
|
| 761 |
}
|
|
@@ -764,7 +704,7 @@
|
|
| 764 |
|
| 765 |
func (etherMan *Client) addExistingRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 766 |
log.Debug("addExistingRollup event detected")
|
| 767 |
-
addExistingRollup, err := etherMan.
|
| 768 |
if err != nil {
|
| 769 |
log.Error("error parsing createNewRollup event. Error: ", err)
|
| 770 |
return err
|
|
@@ -773,66 +713,13 @@
|
|
| 773 |
return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, addExistingRollup.LastVerifiedBatchBeforeUpgrade, addExistingRollup.ForkID, "", addExistingRollup.RollupID)
|
| 774 |
}
|
| 775 |
|
| 776 |
-
func (etherMan *Client) updateEtrogSequence(
|
| 777 |
-
|
| 778 |
-
updateEtrogSequence, err := etherMan.ElderberryZKEVM.ParseUpdateEtrogSequence(vLog)
|
| 779 |
-
if err != nil {
|
| 780 |
-
log.Error("error parsing updateEtrogSequence event. Error: ", err)
|
| 781 |
-
return err
|
| 782 |
-
}
|
| 783 |
-
|
| 784 |
-
// Read the tx for this event.
|
| 785 |
-
tx, err := etherMan.EthClient.TransactionInBlock(ctx, vLog.BlockHash, vLog.TxIndex)
|
| 786 |
-
if err != nil {
|
| 787 |
-
return err
|
| 788 |
-
}
|
| 789 |
-
if tx.Hash() != vLog.TxHash {
|
| 790 |
-
return fmt.Errorf("error: tx hash mismatch. want: %s have: %s", vLog.TxHash, tx.Hash().String())
|
| 791 |
-
}
|
| 792 |
-
msg, err := core.TransactionToMessage(tx, types.NewLondonSigner(tx.ChainId()), big.NewInt(0))
|
| 793 |
-
if err != nil {
|
| 794 |
-
return err
|
| 795 |
-
}
|
| 796 |
-
fullBlock, err := etherMan.EthClient.BlockByHash(ctx, vLog.BlockHash)
|
| 797 |
-
if err != nil {
|
| 798 |
-
return fmt.Errorf("error getting fullBlockInfo. BlockNumber: %d. Error: %w", vLog.BlockNumber, err)
|
| 799 |
-
}
|
| 800 |
-
|
| 801 |
-
log.Info("update Etrog transaction sequence...")
|
| 802 |
-
sequence := UpdateEtrogSequence{
|
| 803 |
-
BatchNumber: updateEtrogSequence.NumBatch,
|
| 804 |
-
SequencerAddr: updateEtrogSequence.Sequencer,
|
| 805 |
-
TxHash: vLog.TxHash,
|
| 806 |
-
Nonce: msg.Nonce,
|
| 807 |
-
PolygonRollupBaseEtrogBatchData: &etrogpolygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 808 |
-
Transactions: updateEtrogSequence.Transactions,
|
| 809 |
-
ForcedGlobalExitRoot: updateEtrogSequence.LastGlobalExitRoot,
|
| 810 |
-
ForcedTimestamp: fullBlock.Time(),
|
| 811 |
-
ForcedBlockHashL1: fullBlock.ParentHash(),
|
| 812 |
-
},
|
| 813 |
-
}
|
| 814 |
-
|
| 815 |
-
if len(*blocks) == 0 || ((*blocks)[len(*blocks)-1].BlockHash != vLog.BlockHash || (*blocks)[len(*blocks)-1].BlockNumber != vLog.BlockNumber) {
|
| 816 |
-
block := prepareBlock(vLog, time.Unix(int64(fullBlock.Time()), 0), fullBlock)
|
| 817 |
-
block.UpdateEtrogSequence = sequence
|
| 818 |
-
*blocks = append(*blocks, block)
|
| 819 |
-
} else if (*blocks)[len(*blocks)-1].BlockHash == vLog.BlockHash && (*blocks)[len(*blocks)-1].BlockNumber == vLog.BlockNumber {
|
| 820 |
-
(*blocks)[len(*blocks)-1].UpdateEtrogSequence = sequence
|
| 821 |
-
} else {
|
| 822 |
-
log.Error("Error processing UpdateEtrogSequence event. BlockHash:", vLog.BlockHash, ". BlockNumber: ", vLog.BlockNumber)
|
| 823 |
-
return fmt.Errorf("error processing UpdateEtrogSequence event")
|
| 824 |
-
}
|
| 825 |
-
or := Order{
|
| 826 |
-
Name: UpdateEtrogSequenceOrder,
|
| 827 |
-
Pos: 0,
|
| 828 |
-
}
|
| 829 |
-
(*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash] = append((*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash], or)
|
| 830 |
-
return nil
|
| 831 |
}
|
| 832 |
|
| 833 |
func (etherMan *Client) initialSequenceBatches(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 834 |
log.Debug("initialSequenceBatches event detected")
|
| 835 |
-
initialSequenceBatches, err := etherMan.
|
| 836 |
if err != nil {
|
| 837 |
log.Error("error parsing initialSequenceBatches event. Error: ", err)
|
| 838 |
return err
|
|
@@ -862,7 +749,7 @@
|
|
| 862 |
SequencerAddr: initialSequenceBatches.Sequencer,
|
| 863 |
TxHash: vLog.TxHash,
|
| 864 |
Nonce: msg.Nonce,
|
| 865 |
-
PolygonRollupBaseEtrogBatchData: &
|
| 866 |
Transactions: initialSequenceBatches.Transactions,
|
| 867 |
ForcedGlobalExitRoot: initialSequenceBatches.LastGlobalExitRoot,
|
| 868 |
ForcedTimestamp: fullBlock.Time(),
|
|
@@ -922,20 +809,20 @@
|
|
| 922 |
|
| 923 |
func (etherMan *Client) updateL1InfoTreeEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 924 |
log.Debug("UpdateL1InfoTree event detected")
|
| 925 |
-
|
| 926 |
if err != nil {
|
| 927 |
return err
|
| 928 |
}
|
| 929 |
|
| 930 |
var gExitRoot GlobalExitRoot
|
| 931 |
-
gExitRoot.MainnetExitRoot =
|
| 932 |
-
gExitRoot.RollupExitRoot =
|
| 933 |
gExitRoot.BlockNumber = vLog.BlockNumber
|
| 934 |
-
gExitRoot.GlobalExitRoot = hash(
|
| 935 |
var block *Block
|
| 936 |
if !isheadBlockInArray(blocks, vLog.BlockHash, vLog.BlockNumber) {
|
| 937 |
// Need to add the block, doesnt mind if inside the blocks because I have to respect the order so insert at end
|
| 938 |
-
block, err = etherMan.
|
| 939 |
if err != nil {
|
| 940 |
return err
|
| 941 |
}
|
|
@@ -955,8 +842,7 @@
|
|
| 955 |
return nil
|
| 956 |
}
|
| 957 |
|
| 958 |
-
|
| 959 |
-
func (etherMan *Client) RetrieveFullBlockForEvent(ctx context.Context, vLog types.Log) (*Block, error) {
|
| 960 |
fullBlock, err := etherMan.EthClient.BlockByHash(ctx, vLog.BlockHash)
|
| 961 |
if err != nil {
|
| 962 |
return nil, fmt.Errorf("error getting hashParent. BlockNumber: %d. Error: %w", vLog.BlockNumber, err)
|
|
@@ -975,11 +861,11 @@
|
|
| 975 |
|
| 976 |
func (etherMan *Client) updateGlobalExitRootEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 977 |
log.Debug("UpdateGlobalExitRoot event detected")
|
| 978 |
-
|
| 979 |
if err != nil {
|
| 980 |
return err
|
| 981 |
}
|
| 982 |
-
return etherMan.processUpdateGlobalExitRootEvent(ctx,
|
| 983 |
}
|
| 984 |
|
| 985 |
func (etherMan *Client) processUpdateGlobalExitRootEvent(ctx context.Context, mainnetExitRoot, rollupExitRoot common.Hash, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
|
@@ -1027,14 +913,14 @@
|
|
| 1027 |
}
|
| 1028 |
|
| 1029 |
// EstimateGasSequenceBatches estimates gas for sending batches
|
| 1030 |
-
func (etherMan *Client) EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) {
|
| 1031 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 1032 |
if err == ErrNotFound {
|
| 1033 |
return nil, ErrPrivateKeyNotFound
|
| 1034 |
}
|
| 1035 |
opts.NoSend = true
|
| 1036 |
|
| 1037 |
-
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase)
|
| 1038 |
if err != nil {
|
| 1039 |
return nil, err
|
| 1040 |
}
|
|
@@ -1043,7 +929,7 @@
|
|
| 1043 |
}
|
| 1044 |
|
| 1045 |
// BuildSequenceBatchesTxData builds a []bytes to be sent to the PoE SC method SequenceBatches.
|
| 1046 |
-
func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (to *common.Address, data []byte, err error) {
|
| 1047 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 1048 |
if err == ErrNotFound {
|
| 1049 |
return nil, nil, fmt.Errorf("failed to build sequence batches, err: %w", ErrPrivateKeyNotFound)
|
|
@@ -1054,7 +940,7 @@
|
|
| 1054 |
opts.GasLimit = uint64(1)
|
| 1055 |
opts.GasPrice = big.NewInt(1)
|
| 1056 |
|
| 1057 |
-
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase)
|
| 1058 |
if err != nil {
|
| 1059 |
return nil, nil, err
|
| 1060 |
}
|
|
@@ -1062,15 +948,15 @@
|
|
| 1062 |
return tx.To(), tx.Data(), nil
|
| 1063 |
}
|
| 1064 |
|
| 1065 |
-
func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) {
|
| 1066 |
-
var batches []
|
| 1067 |
for _, seq := range sequences {
|
| 1068 |
var ger common.Hash
|
| 1069 |
if seq.ForcedBatchTimestamp > 0 {
|
| 1070 |
ger = seq.GlobalExitRoot
|
| 1071 |
}
|
| 1072 |
-
batch :=
|
| 1073 |
-
|
| 1074 |
ForcedGlobalExitRoot: ger,
|
| 1075 |
ForcedTimestamp: uint64(seq.ForcedBatchTimestamp),
|
| 1076 |
ForcedBlockHashL1: seq.PrevBlockHash,
|
|
@@ -1079,12 +965,12 @@
|
|
| 1079 |
batches = append(batches, batch)
|
| 1080 |
}
|
| 1081 |
|
| 1082 |
-
tx, err := etherMan.
|
| 1083 |
if err != nil {
|
| 1084 |
log.Debugf("Batches to send: %+v", batches)
|
| 1085 |
log.Debug("l2CoinBase: ", l2Coinbase)
|
| 1086 |
log.Debug("Sequencer address: ", opts.From)
|
| 1087 |
-
a, err2 :=
|
| 1088 |
if err2 != nil {
|
| 1089 |
log.Error("error getting abi. Error: ", err2)
|
| 1090 |
}
|
|
@@ -1144,7 +1030,7 @@
|
|
| 1144 |
|
| 1145 |
const pendStateNum = 0 // TODO hardcoded for now until we implement the pending state feature
|
| 1146 |
|
| 1147 |
-
tx, err := etherMan.
|
| 1148 |
&opts,
|
| 1149 |
etherMan.RollupID,
|
| 1150 |
pendStateNum,
|
|
@@ -1186,7 +1072,7 @@
|
|
| 1186 |
|
| 1187 |
// GetSendSequenceFee get super/trusted sequencer fee
|
| 1188 |
func (etherMan *Client) GetSendSequenceFee(numBatches uint64) (*big.Int, error) {
|
| 1189 |
-
f, err := etherMan.
|
| 1190 |
if err != nil {
|
| 1191 |
return nil, err
|
| 1192 |
}
|
|
@@ -1196,12 +1082,12 @@
|
|
| 1196 |
|
| 1197 |
// TrustedSequencer gets trusted sequencer address
|
| 1198 |
func (etherMan *Client) TrustedSequencer() (common.Address, error) {
|
| 1199 |
-
return etherMan.
|
| 1200 |
}
|
| 1201 |
|
| 1202 |
func (etherMan *Client) forcedBatchEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1203 |
log.Debug("ForceBatch event detected")
|
| 1204 |
-
fb, err := etherMan.
|
| 1205 |
if err != nil {
|
| 1206 |
return err
|
| 1207 |
}
|
|
@@ -1227,7 +1113,7 @@
|
|
| 1227 |
txData := tx.Data()
|
| 1228 |
// Extract coded txs.
|
| 1229 |
// Load contract ABI
|
| 1230 |
-
abi, err := abi.JSON(strings.NewReader(
|
| 1231 |
if err != nil {
|
| 1232 |
return err
|
| 1233 |
}
|
|
@@ -1276,7 +1162,7 @@
|
|
| 1276 |
func (etherMan *Client) sequencedBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1277 |
log.Debugf("SequenceBatches event detected: txHash: %s", common.Bytes2Hex(vLog.TxHash[:]))
|
| 1278 |
|
| 1279 |
-
sb, err := etherMan.
|
| 1280 |
if err != nil {
|
| 1281 |
return err
|
| 1282 |
}
|
|
@@ -1289,7 +1175,7 @@
|
|
| 1289 |
if tx.Hash() != vLog.TxHash {
|
| 1290 |
return fmt.Errorf("error: tx hash mismatch. want: %s have: %s", vLog.TxHash, tx.Hash().String())
|
| 1291 |
}
|
| 1292 |
-
msg, err := core.TransactionToMessage(tx, types.
|
| 1293 |
if err != nil {
|
| 1294 |
return err
|
| 1295 |
}
|
|
@@ -1298,13 +1184,15 @@
|
|
| 1298 |
if sb.NumBatch != 1 {
|
| 1299 |
methodId := tx.Data()[:4]
|
| 1300 |
log.Debugf("MethodId: %s", common.Bytes2Hex(methodId))
|
| 1301 |
-
if bytes.Equal(methodId, methodIDSequenceBatchesEtrog)
|
| 1302 |
-
|
|
|
|
| 1303 |
if err != nil {
|
| 1304 |
return fmt.Errorf("error decoding the sequences (etrog): %v", err)
|
| 1305 |
}
|
| 1306 |
-
} else if bytes.Equal(methodId, methodIDSequenceBatchesElderberry)
|
| 1307 |
-
|
|
|
|
| 1308 |
if err != nil {
|
| 1309 |
return fmt.Errorf("error decoding the sequences (elderberry): %v", err)
|
| 1310 |
}
|
|
@@ -1345,7 +1233,7 @@
|
|
| 1345 |
|
| 1346 |
func (etherMan *Client) sequencedBatchesPreEtrogEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1347 |
log.Debug("Pre etrog SequenceBatches event detected")
|
| 1348 |
-
sb, err := etherMan.
|
| 1349 |
if err != nil {
|
| 1350 |
return err
|
| 1351 |
}
|
|
@@ -1390,7 +1278,20 @@
|
|
| 1390 |
return nil
|
| 1391 |
}
|
| 1392 |
|
| 1393 |
-
func decodeSequencesElderberry(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1394 |
// Extract coded txs.
|
| 1395 |
// Load contract ABI
|
| 1396 |
smcAbi, err := abi.JSON(strings.NewReader(etrogpolygonzkevm.EtrogpolygonzkevmABI))
|
|
@@ -1398,6 +1299,13 @@
|
|
| 1398 |
return nil, err
|
| 1399 |
}
|
| 1400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1401 |
// Recover Method from signature and ABI
|
| 1402 |
method, err := smcAbi.MethodById(txData[:4])
|
| 1403 |
if err != nil {
|
|
@@ -1409,93 +1317,218 @@
|
|
| 1409 |
if err != nil {
|
| 1410 |
return nil, err
|
| 1411 |
}
|
| 1412 |
-
var sequences []etrogpolygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 1413 |
bytedata, err := json.Marshal(data[0])
|
| 1414 |
if err != nil {
|
| 1415 |
return nil, err
|
| 1416 |
}
|
| 1417 |
-
err = json.Unmarshal(bytedata, &sequences)
|
| 1418 |
-
if err != nil {
|
| 1419 |
-
return nil, err
|
| 1420 |
-
}
|
| 1421 |
-
maxSequenceTimestamp := data[1].(uint64)
|
| 1422 |
-
initSequencedBatchNumber := data[2].(uint64)
|
| 1423 |
-
coinbase := (data[3]).(common.Address)
|
| 1424 |
-
sequencedBatches := make([]SequencedBatch, len(sequences))
|
| 1425 |
|
| 1426 |
-
|
| 1427 |
-
|
| 1428 |
-
|
| 1429 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1430 |
}
|
| 1431 |
-
|
| 1432 |
-
|
| 1433 |
-
|
| 1434 |
-
|
| 1435 |
-
|
| 1436 |
-
|
| 1437 |
-
|
| 1438 |
-
|
| 1439 |
-
|
| 1440 |
-
|
| 1441 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1442 |
}
|
|
|
|
|
|
|
| 1443 |
}
|
| 1444 |
|
| 1445 |
-
return
|
| 1446 |
}
|
| 1447 |
|
| 1448 |
-
|
| 1449 |
-
|
| 1450 |
-
|
| 1451 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1452 |
if err != nil {
|
| 1453 |
return nil, err
|
| 1454 |
}
|
| 1455 |
-
|
| 1456 |
-
// Recover Method from signature and ABI
|
| 1457 |
-
method, err := smcAbi.MethodById(txData[:4])
|
| 1458 |
if err != nil {
|
| 1459 |
return nil, err
|
| 1460 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1461 |
|
| 1462 |
-
|
| 1463 |
-
|
| 1464 |
-
|
| 1465 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1466 |
}
|
| 1467 |
-
|
| 1468 |
-
|
|
|
|
|
|
|
| 1469 |
if err != nil {
|
| 1470 |
return nil, err
|
| 1471 |
}
|
| 1472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1473 |
if err != nil {
|
| 1474 |
return nil, err
|
| 1475 |
}
|
| 1476 |
-
|
| 1477 |
-
|
| 1478 |
-
|
| 1479 |
-
|
| 1480 |
-
|
| 1481 |
-
|
| 1482 |
-
|
| 1483 |
-
|
| 1484 |
-
|
| 1485 |
-
|
| 1486 |
-
Nonce: nonce,
|
| 1487 |
-
Coinbase: coinbase,
|
| 1488 |
-
PolygonRollupBaseEtrogBatchData: &s,
|
| 1489 |
}
|
| 1490 |
}
|
| 1491 |
-
|
| 1492 |
-
return sequencedBatches, nil
|
| 1493 |
}
|
| 1494 |
|
| 1495 |
func decodeSequencesPreEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64) ([]SequencedBatch, error) {
|
| 1496 |
// Extract coded txs.
|
| 1497 |
// Load contract ABI
|
| 1498 |
-
smcAbi, err := abi.JSON(strings.NewReader(
|
| 1499 |
if err != nil {
|
| 1500 |
return nil, err
|
| 1501 |
}
|
|
@@ -1511,7 +1544,7 @@
|
|
| 1511 |
if err != nil {
|
| 1512 |
return nil, err
|
| 1513 |
}
|
| 1514 |
-
var sequences []
|
| 1515 |
bytedata, err := json.Marshal(data[0])
|
| 1516 |
if err != nil {
|
| 1517 |
return nil, err
|
|
@@ -1538,10 +1571,10 @@
|
|
| 1538 |
return sequencedBatches, nil
|
| 1539 |
}
|
| 1540 |
|
| 1541 |
-
func (etherMan *Client)
|
| 1542 |
log.Debug("TrustedVerifyBatches event detected")
|
| 1543 |
-
var vb *
|
| 1544 |
-
vb, err := etherMan.
|
| 1545 |
if err != nil {
|
| 1546 |
log.Error("error parsing TrustedVerifyBatches event. Error: ", err)
|
| 1547 |
return err
|
|
@@ -1551,7 +1584,7 @@
|
|
| 1551 |
|
| 1552 |
func (etherMan *Client) verifyBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1553 |
log.Debug("VerifyBatches event detected")
|
| 1554 |
-
vb, err := etherMan.
|
| 1555 |
if err != nil {
|
| 1556 |
log.Error("error parsing VerifyBatches event. Error: ", err)
|
| 1557 |
return err
|
|
@@ -1598,7 +1631,7 @@
|
|
| 1598 |
|
| 1599 |
func (etherMan *Client) forceSequencedBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1600 |
log.Debug("SequenceForceBatches event detect")
|
| 1601 |
-
fsb, err := etherMan.
|
| 1602 |
if err != nil {
|
| 1603 |
return err
|
| 1604 |
}
|
|
@@ -1647,7 +1680,7 @@
|
|
| 1647 |
func decodeSequencedForceBatches(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, block *types.Block, nonce uint64) ([]SequencedForceBatch, error) {
|
| 1648 |
// Extract coded txs.
|
| 1649 |
// Load contract ABI
|
| 1650 |
-
abi, err := abi.JSON(strings.NewReader(
|
| 1651 |
if err != nil {
|
| 1652 |
return nil, err
|
| 1653 |
}
|
|
@@ -1664,7 +1697,7 @@
|
|
| 1664 |
return nil, err
|
| 1665 |
}
|
| 1666 |
|
| 1667 |
-
var forceBatches []
|
| 1668 |
bytedata, err := json.Marshal(data[0])
|
| 1669 |
if err != nil {
|
| 1670 |
return nil, err
|
|
@@ -1728,11 +1761,18 @@
|
|
| 1728 |
|
| 1729 |
// GetLatestBatchNumber function allows to retrieve the latest proposed batch in the smc
|
| 1730 |
func (etherMan *Client) GetLatestBatchNumber() (uint64, error) {
|
| 1731 |
-
|
|
|
|
| 1732 |
if err != nil {
|
| 1733 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1734 |
}
|
| 1735 |
-
return
|
| 1736 |
}
|
| 1737 |
|
| 1738 |
// GetLatestBlockHeader gets the latest block header from the ethereum
|
|
@@ -1779,11 +1819,18 @@
|
|
| 1779 |
|
| 1780 |
// GetLatestVerifiedBatchNum gets latest verified batch from ethereum
|
| 1781 |
func (etherMan *Client) GetLatestVerifiedBatchNum() (uint64, error) {
|
| 1782 |
-
|
|
|
|
| 1783 |
if err != nil {
|
| 1784 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1785 |
}
|
| 1786 |
-
return
|
| 1787 |
}
|
| 1788 |
|
| 1789 |
// GetTx function get ethereum tx
|
|
@@ -1818,19 +1865,27 @@
|
|
| 1818 |
|
| 1819 |
// GetTrustedSequencerURL Gets the trusted sequencer url from rollup smc
|
| 1820 |
func (etherMan *Client) GetTrustedSequencerURL() (string, error) {
|
| 1821 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1822 |
}
|
| 1823 |
|
| 1824 |
// GetL2ChainID returns L2 Chain ID
|
| 1825 |
func (etherMan *Client) GetL2ChainID() (uint64, error) {
|
| 1826 |
-
chainID, err := etherMan.
|
| 1827 |
-
log.Debug("chainID read from
|
| 1828 |
if err != nil || chainID == 0 {
|
| 1829 |
-
log.Debug("error from
|
| 1830 |
-
rollupData, err := etherMan.
|
| 1831 |
-
log.Debugf("ChainID read from
|
| 1832 |
if err != nil {
|
| 1833 |
-
log.Debug("error from
|
| 1834 |
return 0, err
|
| 1835 |
} else if rollupData.ChainID == 0 {
|
| 1836 |
return rollupData.ChainID, fmt.Errorf("error: chainID received is 0!!")
|
|
@@ -1861,11 +1916,6 @@
|
|
| 1861 |
return etherMan.EthClient.SendTransaction(ctx, tx)
|
| 1862 |
}
|
| 1863 |
|
| 1864 |
-
// PendingNonce returns the pending nonce for the provided account
|
| 1865 |
-
func (etherMan *Client) PendingNonce(ctx context.Context, account common.Address) (uint64, error) {
|
| 1866 |
-
return etherMan.EthClient.PendingNonceAt(ctx, account)
|
| 1867 |
-
}
|
| 1868 |
-
|
| 1869 |
// CurrentNonce returns the current nonce for the provided account
|
| 1870 |
func (etherMan *Client) CurrentNonce(ctx context.Context, account common.Address) (uint64, error) {
|
| 1871 |
return etherMan.EthClient.NonceAt(ctx, account, nil)
|
|
@@ -1898,7 +1948,7 @@
|
|
| 1898 |
opts.BlockNumber = new(big.Int).SetUint64(*blockNumber)
|
| 1899 |
}
|
| 1900 |
|
| 1901 |
-
return etherman.
|
| 1902 |
}
|
| 1903 |
|
| 1904 |
// CheckTxWasMined check if a tx was already mined
|
|
@@ -1955,15 +2005,15 @@
|
|
| 1955 |
}
|
| 1956 |
|
| 1957 |
// LoadAuthFromKeyStore loads an authorization from a key store file
|
| 1958 |
-
func (etherMan *Client) LoadAuthFromKeyStore(path, password string) (*bind.TransactOpts, error) {
|
| 1959 |
-
auth, err := newAuthFromKeystore(path, password, etherMan.l1Cfg.L1ChainID)
|
| 1960 |
if err != nil {
|
| 1961 |
-
return nil, err
|
| 1962 |
}
|
| 1963 |
|
| 1964 |
log.Infof("loaded authorization for address: %v", auth.From.String())
|
| 1965 |
etherMan.auth[auth.From] = auth
|
| 1966 |
-
return &auth, nil
|
| 1967 |
}
|
| 1968 |
|
| 1969 |
// newKeyFromKeystore creates an instance of a keystore key from a keystore file
|
|
@@ -1984,20 +2034,20 @@
|
|
| 1984 |
}
|
| 1985 |
|
| 1986 |
// newAuthFromKeystore an authorization instance from a keystore file
|
| 1987 |
-
func newAuthFromKeystore(path, password string, chainID uint64) (bind.TransactOpts, error) {
|
| 1988 |
log.Infof("reading key from: %v", path)
|
| 1989 |
key, err := newKeyFromKeystore(path, password)
|
| 1990 |
if err != nil {
|
| 1991 |
-
return bind.TransactOpts{}, err
|
| 1992 |
}
|
| 1993 |
if key == nil {
|
| 1994 |
-
return bind.TransactOpts{}, nil
|
| 1995 |
}
|
| 1996 |
auth, err := bind.NewKeyedTransactorWithChainID(key.PrivateKey, new(big.Int).SetUint64(chainID))
|
| 1997 |
if err != nil {
|
| 1998 |
-
return bind.TransactOpts{}, err
|
| 1999 |
}
|
| 2000 |
-
return *auth, nil
|
| 2001 |
}
|
| 2002 |
|
| 2003 |
// getAuthByAddress tries to get an authorization from the authorizations map
|
|
@@ -2025,3 +2075,28 @@
|
|
| 2025 |
|
| 2026 |
return *auth, nil
|
| 2027 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
"context"
|
| 6 |
+
"crypto/ecdsa"
|
| 7 |
"encoding/json"
|
| 8 |
"errors"
|
| 9 |
"fmt"
|
|
|
|
| 44 |
"golang.org/x/crypto/sha3"
|
| 45 |
)
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
var (
|
| 48 |
+
// Events RollupManager
|
| 49 |
setBatchFeeSignatureHash = crypto.Keccak256Hash([]byte("SetBatchFee(uint256)"))
|
| 50 |
setTrustedAggregatorSignatureHash = crypto.Keccak256Hash([]byte("SetTrustedAggregator(address)")) // Used in oldZkEvm as well
|
| 51 |
setVerifyBatchTimeTargetSignatureHash = crypto.Keccak256Hash([]byte("SetVerifyBatchTimeTarget(uint64)")) // Used in oldZkEvm as well
|
|
|
|
| 90 |
updateL1InfoTreeSignatureHash = crypto.Keccak256Hash([]byte("UpdateL1InfoTree(bytes32,bytes32)"))
|
| 91 |
|
| 92 |
// PreLxLy events
|
| 93 |
+
updateGlobalExitRootSignatureHash = crypto.Keccak256Hash([]byte("UpdateGlobalExitRoot(bytes32,bytes32)"))
|
| 94 |
+
oldVerifyBatchesTrustedAggregatorSignatureHash = crypto.Keccak256Hash([]byte("VerifyBatchesTrustedAggregator(uint64,bytes32,address)"))
|
| 95 |
+
transferOwnershipSignatureHash = crypto.Keccak256Hash([]byte("OwnershipTransferred(address,address)"))
|
| 96 |
+
updateZkEVMVersionSignatureHash = crypto.Keccak256Hash([]byte("UpdateZkEVMVersion(uint64,uint64,string)"))
|
| 97 |
+
oldConsolidatePendingStateSignatureHash = crypto.Keccak256Hash([]byte("ConsolidatePendingState(uint64,bytes32,uint64)"))
|
| 98 |
+
oldOverridePendingStateSignatureHash = crypto.Keccak256Hash([]byte("OverridePendingState(uint64,bytes32,address)"))
|
| 99 |
+
sequenceBatchesPreEtrogSignatureHash = crypto.Keccak256Hash([]byte("SequenceBatches(uint64)"))
|
| 100 |
|
| 101 |
// Proxy events
|
| 102 |
initializedProxySignatureHash = crypto.Keccak256Hash([]byte("Initialized(uint8)"))
|
|
|
|
| 109 |
// methodIDSequenceBatchesElderberry: MethodID for sequenceBatches in Elderberry
|
| 110 |
methodIDSequenceBatchesElderberry = []byte{0xde, 0xf5, 0x7e, 0x54} // 0xdef57e54 sequenceBatches((bytes,bytes32,uint64,bytes32)[],uint64,uint64,address)
|
| 111 |
|
| 112 |
+
// methodIDSequenceBatchesValidiumEtrog: MethodID for sequenceBatchesValidium in Etrog
|
| 113 |
+
methodIDSequenceBatchesValidiumEtrog = []byte{0x2d, 0x72, 0xc2, 0x48} // 0x2d72c248 sequenceBatchesValidium((bytes32,bytes32,uint64,bytes32)[],address,bytes)
|
| 114 |
+
// methodIDSequenceBatchesValidiumElderberry: MethodID for sequenceBatchesValidium in Elderberry
|
| 115 |
+
methodIDSequenceBatchesValidiumElderberry = []byte{0xdb, 0x5b, 0x0e, 0xd7} // 0xdb5b0ed7 sequenceBatchesValidium((bytes32,bytes32,uint64,bytes32)[],uint64,uint64,address,bytes)
|
| 116 |
+
|
| 117 |
// ErrNotFound is used when the object is not found
|
| 118 |
ErrNotFound = errors.New("not found")
|
| 119 |
// ErrIsReadOnlyMode is used when the EtherMan client is in read-only mode.
|
|
|
|
| 164 |
ethereum.LogFilterer
|
| 165 |
ethereum.TransactionReader
|
| 166 |
ethereum.TransactionSender
|
|
|
|
| 167 |
|
| 168 |
bind.DeployBackend
|
| 169 |
}
|
|
|
|
| 189 |
|
| 190 |
// Client is a simple implementation of EtherMan.
|
| 191 |
type Client struct {
|
| 192 |
+
EthClient ethereumClient
|
| 193 |
+
OldZkEVM *oldpolygonzkevm.Oldpolygonzkevm
|
| 194 |
+
EtrogZKEVM *etrogpolygonzkevm.Etrogpolygonzkevm
|
| 195 |
+
ZkEVM *polygonzkevm.Polygonzkevm
|
| 196 |
+
RollupManager *polygonrollupmanager.Polygonrollupmanager
|
| 197 |
+
GlobalExitRootManager *polygonzkevmglobalexitroot.Polygonzkevmglobalexitroot
|
| 198 |
+
OldGlobalExitRootManager *oldpolygonzkevmglobalexitroot.Oldpolygonzkevmglobalexitroot
|
| 199 |
+
Pol *pol.Pol
|
| 200 |
+
DAProtocol *dataavailabilityprotocol.Dataavailabilityprotocol
|
| 201 |
+
SCAddresses []common.Address
|
| 202 |
|
| 203 |
RollupID uint32
|
| 204 |
|
| 205 |
GasProviders externalGasProviders
|
| 206 |
|
| 207 |
+
l1Cfg L1Config
|
| 208 |
+
cfg Config
|
| 209 |
+
auth map[common.Address]bind.TransactOpts // empty in case of read-only client
|
| 210 |
+
|
| 211 |
+
da dataavailability.BatchDataProvider
|
| 212 |
+
state stateProvider
|
| 213 |
}
|
| 214 |
|
| 215 |
// NewClient creates a new etherman.
|
| 216 |
+
func NewClient(cfg Config, l1Config L1Config, da dataavailability.BatchDataProvider, st stateProvider) (*Client, error) {
|
| 217 |
// Connect to ethereum node
|
| 218 |
ethClient, err := ethclient.Dial(cfg.URL)
|
| 219 |
if err != nil {
|
| 220 |
log.Errorf("error connecting to %s: %+v", cfg.URL, err)
|
| 221 |
return nil, err
|
| 222 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
// Create smc clients
|
| 224 |
+
zkevm, err := polygonzkevm.NewPolygonzkevm(l1Config.ZkEVMAddr, ethClient)
|
| 225 |
if err != nil {
|
| 226 |
log.Errorf("error creating Polygonzkevm client (%s). Error: %w", l1Config.ZkEVMAddr.String(), err)
|
| 227 |
return nil, err
|
| 228 |
}
|
| 229 |
+
etrogZkevm, err := etrogpolygonzkevm.NewEtrogpolygonzkevm(l1Config.RollupManagerAddr, ethClient)
|
| 230 |
if err != nil {
|
| 231 |
+
log.Errorf("error creating NewEtrogPolygonzkevm client (%s). Error: %w", l1Config.RollupManagerAddr.String(), err)
|
| 232 |
return nil, err
|
| 233 |
}
|
| 234 |
+
oldZkevm, err := oldpolygonzkevm.NewOldpolygonzkevm(l1Config.RollupManagerAddr, ethClient)
|
| 235 |
if err != nil {
|
| 236 |
+
log.Errorf("error creating NewOldpolygonzkevm client (%s). Error: %w", l1Config.RollupManagerAddr.String(), err)
|
| 237 |
return nil, err
|
| 238 |
}
|
| 239 |
+
rollupManager, err := polygonrollupmanager.NewPolygonrollupmanager(l1Config.RollupManagerAddr, ethClient)
|
| 240 |
if err != nil {
|
| 241 |
log.Errorf("error creating NewPolygonrollupmanager client (%s). Error: %w", l1Config.RollupManagerAddr.String(), err)
|
| 242 |
return nil, err
|
| 243 |
}
|
| 244 |
+
globalExitRoot, err := polygonzkevmglobalexitroot.NewPolygonzkevmglobalexitroot(l1Config.GlobalExitRootManagerAddr, ethClient)
|
| 245 |
if err != nil {
|
| 246 |
log.Errorf("error creating NewPolygonzkevmglobalexitroot client (%s). Error: %w", l1Config.GlobalExitRootManagerAddr.String(), err)
|
| 247 |
return nil, err
|
| 248 |
}
|
| 249 |
+
oldGlobalExitRoot, err := oldpolygonzkevmglobalexitroot.NewOldpolygonzkevmglobalexitroot(l1Config.GlobalExitRootManagerAddr, ethClient)
|
| 250 |
if err != nil {
|
| 251 |
+
log.Errorf("error creating NewOldpolygonzkevmglobalexitroot client (%s). Error: %w", l1Config.GlobalExitRootManagerAddr.String(), err)
|
| 252 |
return nil, err
|
| 253 |
}
|
| 254 |
pol, err := pol.NewPol(l1Config.PolAddr, ethClient)
|
|
|
|
| 256 |
log.Errorf("error creating NewPol client (%s). Error: %w", l1Config.PolAddr.String(), err)
|
| 257 |
return nil, err
|
| 258 |
}
|
| 259 |
+
dapAddr, err := zkevm.DataAvailabilityProtocol(&bind.CallOpts{Pending: false})
|
| 260 |
+
if err != nil {
|
| 261 |
+
return nil, err
|
| 262 |
+
}
|
| 263 |
+
dap, err := dataavailabilityprotocol.NewDataavailabilityprotocol(dapAddr, ethClient)
|
| 264 |
if err != nil {
|
|
|
|
| 265 |
return nil, err
|
| 266 |
}
|
| 267 |
+
var scAddresses []common.Address
|
| 268 |
scAddresses = append(scAddresses, l1Config.ZkEVMAddr, l1Config.RollupManagerAddr, l1Config.GlobalExitRootManagerAddr)
|
| 269 |
|
| 270 |
gProviders := []ethereum.GasPricer{ethClient}
|
|
|
|
| 279 |
}
|
| 280 |
metrics.Register()
|
| 281 |
// Get RollupID
|
| 282 |
+
rollupID, err := rollupManager.RollupAddressToID(&bind.CallOpts{Pending: false}, l1Config.ZkEVMAddr)
|
| 283 |
if err != nil {
|
| 284 |
log.Debugf("error rollupManager.RollupAddressToID(%s). Error: %w", l1Config.RollupManagerAddr, err)
|
| 285 |
return nil, err
|
| 286 |
}
|
| 287 |
log.Debug("rollupID: ", rollupID)
|
| 288 |
|
| 289 |
+
return &Client{
|
| 290 |
+
EthClient: ethClient,
|
| 291 |
+
ZkEVM: zkevm,
|
| 292 |
+
EtrogZKEVM: etrogZkevm,
|
| 293 |
+
OldZkEVM: oldZkevm,
|
| 294 |
+
RollupManager: rollupManager,
|
| 295 |
+
Pol: pol,
|
| 296 |
+
GlobalExitRootManager: globalExitRoot,
|
| 297 |
+
DAProtocol: dap,
|
| 298 |
+
OldGlobalExitRootManager: oldGlobalExitRoot,
|
| 299 |
+
SCAddresses: scAddresses,
|
| 300 |
+
RollupID: rollupID,
|
| 301 |
GasProviders: externalGasProviders{
|
| 302 |
MultiGasProvider: cfg.MultiGasProvider,
|
| 303 |
Providers: gProviders,
|
| 304 |
},
|
| 305 |
+
l1Cfg: l1Config,
|
| 306 |
+
cfg: cfg,
|
| 307 |
+
auth: map[common.Address]bind.TransactOpts{},
|
| 308 |
+
da: da,
|
| 309 |
+
state: st,
|
| 310 |
+
}, nil
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
}
|
| 312 |
|
| 313 |
// VerifyGenBlockNumber verifies if the genesis Block Number is valid
|
| 314 |
func (etherMan *Client) VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error) {
|
| 315 |
+
// TODO: do not assume that only one rollup will be attached to the rollup manager in the same L1 block
|
| 316 |
start := time.Now()
|
| 317 |
log.Info("Verifying genesis blockNumber: ", genBlockNumber)
|
| 318 |
// Filter query
|
|
|
|
| 330 |
if len(logs) == 0 {
|
| 331 |
return false, fmt.Errorf("the specified genBlockNumber in config file does not contain any forkID event. Please use the proper blockNumber.")
|
| 332 |
}
|
| 333 |
+
var zkevmVersion oldpolygonzkevm.OldpolygonzkevmUpdateZkEVMVersion
|
| 334 |
switch logs[0].Topics[0] {
|
| 335 |
case updateZkEVMVersionSignatureHash:
|
| 336 |
log.Debug("UpdateZkEVMVersion event detected during the Verification of the GenBlockNumber")
|
| 337 |
+
zkevmV, err := etherMan.OldZkEVM.ParseUpdateZkEVMVersion(logs[0])
|
| 338 |
if err != nil {
|
| 339 |
return false, err
|
| 340 |
}
|
|
|
|
| 343 |
}
|
| 344 |
case createNewRollupSignatureHash:
|
| 345 |
log.Debug("CreateNewRollup event detected during the Verification of the GenBlockNumber")
|
| 346 |
+
createNewRollupEvent, err := etherMan.RollupManager.ParseCreateNewRollup(logs[0])
|
| 347 |
if err != nil {
|
| 348 |
return false, err
|
| 349 |
}
|
| 350 |
// Query to get the forkID
|
| 351 |
+
rollupType, err := etherMan.RollupManager.RollupTypeMap(&bind.CallOpts{Pending: false}, createNewRollupEvent.RollupTypeID)
|
| 352 |
if err != nil {
|
| 353 |
log.Error(err)
|
| 354 |
return false, err
|
|
|
|
| 363 |
return true, nil
|
| 364 |
}
|
| 365 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
// GetForks returns fork information
|
| 367 |
func (etherMan *Client) GetForks(ctx context.Context, genBlockNumber uint64, lastL1BlockSynced uint64) ([]state.ForkIDInterval, error) {
|
| 368 |
log.Debug("Getting forkIDs from blockNumber: ", genBlockNumber)
|
| 369 |
start := time.Now()
|
| 370 |
var logs []types.Log
|
| 371 |
+
|
| 372 |
if lastL1BlockSynced < genBlockNumber {
|
| 373 |
lastL1BlockSynced = genBlockNumber
|
| 374 |
}
|
| 375 |
+
|
| 376 |
log.Debug("Using ForkIDChunkSize: ", etherMan.cfg.ForkIDChunkSize)
|
| 377 |
for i := genBlockNumber; i <= lastL1BlockSynced; i = i + etherMan.cfg.ForkIDChunkSize + 1 {
|
| 378 |
final := i + etherMan.cfg.ForkIDChunkSize
|
|
|
|
| 397 |
|
| 398 |
var forks []state.ForkIDInterval
|
| 399 |
for i, l := range logs {
|
| 400 |
+
var zkevmVersion oldpolygonzkevm.OldpolygonzkevmUpdateZkEVMVersion
|
| 401 |
switch l.Topics[0] {
|
| 402 |
case updateZkEVMVersionSignatureHash:
|
| 403 |
log.Debug("updateZkEVMVersion Event received")
|
| 404 |
+
zkevmV, err := etherMan.OldZkEVM.ParseUpdateZkEVMVersion(l)
|
| 405 |
if err != nil {
|
| 406 |
return []state.ForkIDInterval{}, err
|
| 407 |
}
|
|
|
|
| 410 |
}
|
| 411 |
case updateRollupSignatureHash:
|
| 412 |
log.Debug("updateRollup Event received")
|
| 413 |
+
updateRollupEvent, err := etherMan.RollupManager.ParseUpdateRollup(l)
|
| 414 |
if err != nil {
|
| 415 |
return []state.ForkIDInterval{}, err
|
| 416 |
}
|
|
|
|
| 418 |
continue
|
| 419 |
}
|
| 420 |
// Query to get the forkID
|
| 421 |
+
rollupType, err := etherMan.RollupManager.RollupTypeMap(&bind.CallOpts{Pending: false}, updateRollupEvent.NewRollupTypeID)
|
| 422 |
if err != nil {
|
| 423 |
return []state.ForkIDInterval{}, err
|
| 424 |
}
|
|
|
|
| 427 |
|
| 428 |
case addExistingRollupSignatureHash:
|
| 429 |
log.Debug("addExistingRollup Event received")
|
| 430 |
+
addExistingRollupEvent, err := etherMan.RollupManager.ParseAddExistingRollup(l)
|
| 431 |
if err != nil {
|
| 432 |
return []state.ForkIDInterval{}, err
|
| 433 |
}
|
|
|
|
| 439 |
|
| 440 |
case createNewRollupSignatureHash:
|
| 441 |
log.Debug("createNewRollup Event received")
|
| 442 |
+
createNewRollupEvent, err := etherMan.RollupManager.ParseCreateNewRollup(l)
|
| 443 |
if err != nil {
|
| 444 |
return []state.ForkIDInterval{}, err
|
| 445 |
}
|
|
|
|
| 447 |
continue
|
| 448 |
}
|
| 449 |
// Query to get the forkID
|
| 450 |
+
rollupType, err := etherMan.RollupManager.RollupTypeMap(&bind.CallOpts{Pending: false}, createNewRollupEvent.RollupTypeID)
|
| 451 |
if err != nil {
|
| 452 |
log.Error(err)
|
| 453 |
return []state.ForkIDInterval{}, err
|
|
|
|
| 499 |
return blocks, blocksOrder, nil
|
| 500 |
}
|
| 501 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 502 |
// Order contains the event order to let the synchronizer store the information following this order.
|
| 503 |
type Order struct {
|
| 504 |
Name EventOrder
|
|
|
|
| 529 |
metrics.ReadAndProcessAllEventsTime(time.Since(start))
|
| 530 |
return blocks, blocksOrder, nil
|
| 531 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 532 |
|
| 533 |
+
func (etherMan *Client) processEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 534 |
switch vLog.Topics[0] {
|
| 535 |
case sequenceBatchesSignatureHash:
|
| 536 |
return etherMan.sequencedBatchesEvent(ctx, vLog, blocks, blocksOrder)
|
|
|
|
| 552 |
case rollupManagerVerifyBatchesSignatureHash:
|
| 553 |
log.Debug("RollupManagerVerifyBatches event detected. Ignoring...")
|
| 554 |
return nil
|
| 555 |
+
case oldVerifyBatchesTrustedAggregatorSignatureHash:
|
| 556 |
+
return etherMan.oldVerifyBatchesTrustedAggregatorEvent(ctx, vLog, blocks, blocksOrder)
|
| 557 |
case verifyBatchesSignatureHash:
|
| 558 |
return etherMan.verifyBatchesEvent(ctx, vLog, blocks, blocksOrder)
|
| 559 |
case sequenceForceBatchesSignatureHash:
|
|
|
|
| 593 |
case consolidatePendingStateSignatureHash:
|
| 594 |
log.Debug("ConsolidatePendingState event detected. Ignoring...")
|
| 595 |
return nil
|
| 596 |
+
case oldConsolidatePendingStateSignatureHash:
|
| 597 |
+
log.Debug("OldConsolidatePendingState event detected. Ignoring...")
|
| 598 |
return nil
|
| 599 |
case setTrustedAggregatorTimeoutSignatureHash:
|
| 600 |
log.Debug("SetTrustedAggregatorTimeout event detected. Ignoring...")
|
|
|
|
| 629 |
case overridePendingStateSignatureHash:
|
| 630 |
log.Debug("OverridePendingState event detected. Ignoring...")
|
| 631 |
return nil
|
| 632 |
+
case oldOverridePendingStateSignatureHash:
|
| 633 |
+
log.Debug("OldOverridePendingState event detected. Ignoring...")
|
| 634 |
return nil
|
| 635 |
case roleAdminChangedSignatureHash:
|
| 636 |
log.Debug("RoleAdminChanged event detected. Ignoring...")
|
|
|
|
| 666 |
|
| 667 |
func (etherMan *Client) updateZkevmVersion(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 668 |
log.Debug("UpdateZkEVMVersion event detected")
|
| 669 |
+
zkevmVersion, err := etherMan.OldZkEVM.ParseUpdateZkEVMVersion(vLog)
|
| 670 |
if err != nil {
|
| 671 |
log.Error("error parsing UpdateZkEVMVersion event. Error: ", err)
|
| 672 |
return err
|
|
|
|
| 676 |
|
| 677 |
func (etherMan *Client) updateRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 678 |
log.Debug("UpdateRollup event detected")
|
| 679 |
+
updateRollup, err := etherMan.RollupManager.ParseUpdateRollup(vLog)
|
| 680 |
if err != nil {
|
| 681 |
log.Error("error parsing UpdateRollup event. Error: ", err)
|
| 682 |
return err
|
| 683 |
}
|
| 684 |
+
rollupType, err := etherMan.RollupManager.RollupTypeMap(&bind.CallOpts{Pending: false}, updateRollup.NewRollupTypeID)
|
| 685 |
if err != nil {
|
| 686 |
return err
|
| 687 |
}
|
|
|
|
| 690 |
|
| 691 |
func (etherMan *Client) createNewRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 692 |
log.Debug("createNewRollup event detected")
|
| 693 |
+
createRollup, err := etherMan.RollupManager.ParseCreateNewRollup(vLog)
|
| 694 |
if err != nil {
|
| 695 |
log.Error("error parsing createNewRollup event. Error: ", err)
|
| 696 |
return err
|
| 697 |
}
|
| 698 |
+
rollupType, err := etherMan.RollupManager.RollupTypeMap(&bind.CallOpts{Pending: false}, createRollup.RollupTypeID)
|
| 699 |
if err != nil {
|
| 700 |
return err
|
| 701 |
}
|
|
|
|
| 704 |
|
| 705 |
func (etherMan *Client) addExistingRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 706 |
log.Debug("addExistingRollup event detected")
|
| 707 |
+
addExistingRollup, err := etherMan.RollupManager.ParseAddExistingRollup(vLog)
|
| 708 |
if err != nil {
|
| 709 |
log.Error("error parsing createNewRollup event. Error: ", err)
|
| 710 |
return err
|
|
|
|
| 713 |
return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, addExistingRollup.LastVerifiedBatchBeforeUpgrade, addExistingRollup.ForkID, "", addExistingRollup.RollupID)
|
| 714 |
}
|
| 715 |
|
| 716 |
+
func (etherMan *Client) updateEtrogSequence(_ context.Context, _ types.Log, _ *[]Block, _ *map[common.Hash][]Order) error {
|
| 717 |
+
return errors.New("upgrading validiums to etrog not supported")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 718 |
}
|
| 719 |
|
| 720 |
func (etherMan *Client) initialSequenceBatches(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 721 |
log.Debug("initialSequenceBatches event detected")
|
| 722 |
+
initialSequenceBatches, err := etherMan.ZkEVM.ParseInitialSequenceBatches(vLog)
|
| 723 |
if err != nil {
|
| 724 |
log.Error("error parsing initialSequenceBatches event. Error: ", err)
|
| 725 |
return err
|
|
|
|
| 749 |
SequencerAddr: initialSequenceBatches.Sequencer,
|
| 750 |
TxHash: vLog.TxHash,
|
| 751 |
Nonce: msg.Nonce,
|
| 752 |
+
PolygonRollupBaseEtrogBatchData: &polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 753 |
Transactions: initialSequenceBatches.Transactions,
|
| 754 |
ForcedGlobalExitRoot: initialSequenceBatches.LastGlobalExitRoot,
|
| 755 |
ForcedTimestamp: fullBlock.Time(),
|
|
|
|
| 809 |
|
| 810 |
func (etherMan *Client) updateL1InfoTreeEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 811 |
log.Debug("UpdateL1InfoTree event detected")
|
| 812 |
+
globalExitRootL1InfoTree, err := etherMan.GlobalExitRootManager.ParseUpdateL1InfoTree(vLog)
|
| 813 |
if err != nil {
|
| 814 |
return err
|
| 815 |
}
|
| 816 |
|
| 817 |
var gExitRoot GlobalExitRoot
|
| 818 |
+
gExitRoot.MainnetExitRoot = globalExitRootL1InfoTree.MainnetExitRoot
|
| 819 |
+
gExitRoot.RollupExitRoot = globalExitRootL1InfoTree.RollupExitRoot
|
| 820 |
gExitRoot.BlockNumber = vLog.BlockNumber
|
| 821 |
+
gExitRoot.GlobalExitRoot = hash(globalExitRootL1InfoTree.MainnetExitRoot, globalExitRootL1InfoTree.RollupExitRoot)
|
| 822 |
var block *Block
|
| 823 |
if !isheadBlockInArray(blocks, vLog.BlockHash, vLog.BlockNumber) {
|
| 824 |
// Need to add the block, doesnt mind if inside the blocks because I have to respect the order so insert at end
|
| 825 |
+
block, err = etherMan.retrieveFullBlockForEvent(ctx, vLog)
|
| 826 |
if err != nil {
|
| 827 |
return err
|
| 828 |
}
|
|
|
|
| 842 |
return nil
|
| 843 |
}
|
| 844 |
|
| 845 |
+
func (etherMan *Client) retrieveFullBlockForEvent(ctx context.Context, vLog types.Log) (*Block, error) {
|
|
|
|
| 846 |
fullBlock, err := etherMan.EthClient.BlockByHash(ctx, vLog.BlockHash)
|
| 847 |
if err != nil {
|
| 848 |
return nil, fmt.Errorf("error getting hashParent. BlockNumber: %d. Error: %w", vLog.BlockNumber, err)
|
|
|
|
| 861 |
|
| 862 |
func (etherMan *Client) updateGlobalExitRootEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 863 |
log.Debug("UpdateGlobalExitRoot event detected")
|
| 864 |
+
oldglobalExitRoot, err := etherMan.OldGlobalExitRootManager.ParseUpdateGlobalExitRoot(vLog)
|
| 865 |
if err != nil {
|
| 866 |
return err
|
| 867 |
}
|
| 868 |
+
return etherMan.processUpdateGlobalExitRootEvent(ctx, oldglobalExitRoot.MainnetExitRoot, oldglobalExitRoot.RollupExitRoot, vLog, blocks, blocksOrder)
|
| 869 |
}
|
| 870 |
|
| 871 |
func (etherMan *Client) processUpdateGlobalExitRootEvent(ctx context.Context, mainnetExitRoot, rollupExitRoot common.Hash, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
|
|
|
| 913 |
}
|
| 914 |
|
| 915 |
// EstimateGasSequenceBatches estimates gas for sending batches
|
| 916 |
+
func (etherMan *Client) EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address, dataAvailabilityMessage []byte) (*types.Transaction, error) {
|
| 917 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 918 |
if err == ErrNotFound {
|
| 919 |
return nil, ErrPrivateKeyNotFound
|
| 920 |
}
|
| 921 |
opts.NoSend = true
|
| 922 |
|
| 923 |
+
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase, dataAvailabilityMessage)
|
| 924 |
if err != nil {
|
| 925 |
return nil, err
|
| 926 |
}
|
|
|
|
| 929 |
}
|
| 930 |
|
| 931 |
// BuildSequenceBatchesTxData builds a []bytes to be sent to the PoE SC method SequenceBatches.
|
| 932 |
+
func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address, dataAvailabilityMessage []byte) (to *common.Address, data []byte, err error) {
|
| 933 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 934 |
if err == ErrNotFound {
|
| 935 |
return nil, nil, fmt.Errorf("failed to build sequence batches, err: %w", ErrPrivateKeyNotFound)
|
|
|
|
| 940 |
opts.GasLimit = uint64(1)
|
| 941 |
opts.GasPrice = big.NewInt(1)
|
| 942 |
|
| 943 |
+
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase, dataAvailabilityMessage)
|
| 944 |
if err != nil {
|
| 945 |
return nil, nil, err
|
| 946 |
}
|
|
|
|
| 948 |
return tx.To(), tx.Data(), nil
|
| 949 |
}
|
| 950 |
|
| 951 |
+
func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address, dataAvailabilityMessage []byte) (*types.Transaction, error) {
|
| 952 |
+
var batches []polygonzkevm.PolygonValidiumEtrogValidiumBatchData
|
| 953 |
for _, seq := range sequences {
|
| 954 |
var ger common.Hash
|
| 955 |
if seq.ForcedBatchTimestamp > 0 {
|
| 956 |
ger = seq.GlobalExitRoot
|
| 957 |
}
|
| 958 |
+
batch := polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 959 |
+
TransactionsHash: crypto.Keccak256Hash(seq.BatchL2Data),
|
| 960 |
ForcedGlobalExitRoot: ger,
|
| 961 |
ForcedTimestamp: uint64(seq.ForcedBatchTimestamp),
|
| 962 |
ForcedBlockHashL1: seq.PrevBlockHash,
|
|
|
|
| 965 |
batches = append(batches, batch)
|
| 966 |
}
|
| 967 |
|
| 968 |
+
tx, err := etherMan.ZkEVM.SequenceBatchesValidium(&opts, batches, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase, dataAvailabilityMessage)
|
| 969 |
if err != nil {
|
| 970 |
log.Debugf("Batches to send: %+v", batches)
|
| 971 |
log.Debug("l2CoinBase: ", l2Coinbase)
|
| 972 |
log.Debug("Sequencer address: ", opts.From)
|
| 973 |
+
a, err2 := polygonzkevm.PolygonzkevmMetaData.GetAbi()
|
| 974 |
if err2 != nil {
|
| 975 |
log.Error("error getting abi. Error: ", err2)
|
| 976 |
}
|
|
|
|
| 1030 |
|
| 1031 |
const pendStateNum = 0 // TODO hardcoded for now until we implement the pending state feature
|
| 1032 |
|
| 1033 |
+
tx, err := etherMan.RollupManager.VerifyBatchesTrustedAggregator(
|
| 1034 |
&opts,
|
| 1035 |
etherMan.RollupID,
|
| 1036 |
pendStateNum,
|
|
|
|
| 1072 |
|
| 1073 |
// GetSendSequenceFee get super/trusted sequencer fee
|
| 1074 |
func (etherMan *Client) GetSendSequenceFee(numBatches uint64) (*big.Int, error) {
|
| 1075 |
+
f, err := etherMan.RollupManager.GetBatchFee(&bind.CallOpts{Pending: false})
|
| 1076 |
if err != nil {
|
| 1077 |
return nil, err
|
| 1078 |
}
|
|
|
|
| 1082 |
|
| 1083 |
// TrustedSequencer gets trusted sequencer address
|
| 1084 |
func (etherMan *Client) TrustedSequencer() (common.Address, error) {
|
| 1085 |
+
return etherMan.ZkEVM.TrustedSequencer(&bind.CallOpts{Pending: false})
|
| 1086 |
}
|
| 1087 |
|
| 1088 |
func (etherMan *Client) forcedBatchEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1089 |
log.Debug("ForceBatch event detected")
|
| 1090 |
+
fb, err := etherMan.ZkEVM.ParseForceBatch(vLog)
|
| 1091 |
if err != nil {
|
| 1092 |
return err
|
| 1093 |
}
|
|
|
|
| 1113 |
txData := tx.Data()
|
| 1114 |
// Extract coded txs.
|
| 1115 |
// Load contract ABI
|
| 1116 |
+
abi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI))
|
| 1117 |
if err != nil {
|
| 1118 |
return err
|
| 1119 |
}
|
|
|
|
| 1162 |
func (etherMan *Client) sequencedBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1163 |
log.Debugf("SequenceBatches event detected: txHash: %s", common.Bytes2Hex(vLog.TxHash[:]))
|
| 1164 |
|
| 1165 |
+
sb, err := etherMan.ZkEVM.ParseSequenceBatches(vLog)
|
| 1166 |
if err != nil {
|
| 1167 |
return err
|
| 1168 |
}
|
|
|
|
| 1175 |
if tx.Hash() != vLog.TxHash {
|
| 1176 |
return fmt.Errorf("error: tx hash mismatch. want: %s have: %s", vLog.TxHash, tx.Hash().String())
|
| 1177 |
}
|
| 1178 |
+
msg, err := core.TransactionToMessage(tx, types.NewLondonSigner(tx.ChainId()), big.NewInt(0))
|
| 1179 |
if err != nil {
|
| 1180 |
return err
|
| 1181 |
}
|
|
|
|
| 1184 |
if sb.NumBatch != 1 {
|
| 1185 |
methodId := tx.Data()[:4]
|
| 1186 |
log.Debugf("MethodId: %s", common.Bytes2Hex(methodId))
|
| 1187 |
+
if bytes.Equal(methodId, methodIDSequenceBatchesEtrog) ||
|
| 1188 |
+
bytes.Equal(methodId, methodIDSequenceBatchesValidiumEtrog) {
|
| 1189 |
+
sequences, err = decodeSequencesEtrog(tx.Data(), sb.NumBatch, msg.From, vLog.TxHash, msg.Nonce, sb.L1InfoRoot, etherMan.da, etherMan.state)
|
| 1190 |
if err != nil {
|
| 1191 |
return fmt.Errorf("error decoding the sequences (etrog): %v", err)
|
| 1192 |
}
|
| 1193 |
+
} else if bytes.Equal(methodId, methodIDSequenceBatchesElderberry) ||
|
| 1194 |
+
bytes.Equal(methodId, methodIDSequenceBatchesValidiumElderberry) {
|
| 1195 |
+
sequences, err = decodeSequencesElderberry(tx.Data(), sb.NumBatch, msg.From, vLog.TxHash, msg.Nonce, sb.L1InfoRoot, etherMan.da, etherMan.state)
|
| 1196 |
if err != nil {
|
| 1197 |
return fmt.Errorf("error decoding the sequences (elderberry): %v", err)
|
| 1198 |
}
|
|
|
|
| 1233 |
|
| 1234 |
func (etherMan *Client) sequencedBatchesPreEtrogEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1235 |
log.Debug("Pre etrog SequenceBatches event detected")
|
| 1236 |
+
sb, err := etherMan.OldZkEVM.ParseSequenceBatches(vLog)
|
| 1237 |
if err != nil {
|
| 1238 |
return err
|
| 1239 |
}
|
|
|
|
| 1278 |
return nil
|
| 1279 |
}
|
| 1280 |
|
| 1281 |
+
func decodeSequencesElderberry(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64,
|
| 1282 |
+
l1InfoRoot common.Hash, da dataavailability.BatchDataProvider, st stateProvider) ([]SequencedBatch, error) {
|
| 1283 |
+
// Extract coded txs.
|
| 1284 |
+
// Load contract ABI
|
| 1285 |
+
smcAbi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI))
|
| 1286 |
+
if err != nil {
|
| 1287 |
+
return nil, err
|
| 1288 |
+
}
|
| 1289 |
+
|
| 1290 |
+
return decodeSequencedBatches(smcAbi, txData, state.FORKID_ELDERBERRY, lastBatchNumber, sequencer, txHash, nonce, l1InfoRoot, da, st)
|
| 1291 |
+
}
|
| 1292 |
+
|
| 1293 |
+
func decodeSequencesEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash,
|
| 1294 |
+
da dataavailability.BatchDataProvider, st stateProvider) ([]SequencedBatch, error) {
|
| 1295 |
// Extract coded txs.
|
| 1296 |
// Load contract ABI
|
| 1297 |
smcAbi, err := abi.JSON(strings.NewReader(etrogpolygonzkevm.EtrogpolygonzkevmABI))
|
|
|
|
| 1299 |
return nil, err
|
| 1300 |
}
|
| 1301 |
|
| 1302 |
+
return decodeSequencedBatches(smcAbi, txData, state.FORKID_ETROG, lastBatchNumber, sequencer, txHash, nonce, l1InfoRoot, da, st)
|
| 1303 |
+
}
|
| 1304 |
+
|
| 1305 |
+
// decodeSequencedBatches decodes provided data, based on the funcName, whether it is rollup or validium data and returns sequenced batches
|
| 1306 |
+
func decodeSequencedBatches(smcAbi abi.ABI, txData []byte, forkID uint64, lastBatchNumber uint64,
|
| 1307 |
+
sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash,
|
| 1308 |
+
da dataavailability.BatchDataProvider, st stateProvider) ([]SequencedBatch, error) {
|
| 1309 |
// Recover Method from signature and ABI
|
| 1310 |
method, err := smcAbi.MethodById(txData[:4])
|
| 1311 |
if err != nil {
|
|
|
|
| 1317 |
if err != nil {
|
| 1318 |
return nil, err
|
| 1319 |
}
|
|
|
|
| 1320 |
bytedata, err := json.Marshal(data[0])
|
| 1321 |
if err != nil {
|
| 1322 |
return nil, err
|
| 1323 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1324 |
|
| 1325 |
+
var (
|
| 1326 |
+
maxSequenceTimestamp uint64
|
| 1327 |
+
initSequencedBatchNumber uint64
|
| 1328 |
+
coinbase common.Address
|
| 1329 |
+
)
|
| 1330 |
+
|
| 1331 |
+
switch method.Name {
|
| 1332 |
+
case "sequenceBatches":
|
| 1333 |
+
var sequences []polygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 1334 |
+
err := json.Unmarshal(bytedata, &sequences)
|
| 1335 |
+
if err != nil {
|
| 1336 |
+
return nil, err
|
| 1337 |
}
|
| 1338 |
+
|
| 1339 |
+
switch forkID {
|
| 1340 |
+
case state.FORKID_ETROG:
|
| 1341 |
+
coinbase = data[1].(common.Address)
|
| 1342 |
+
|
| 1343 |
+
case state.FORKID_ELDERBERRY:
|
| 1344 |
+
maxSequenceTimestamp = data[1].(uint64)
|
| 1345 |
+
initSequencedBatchNumber = data[2].(uint64)
|
| 1346 |
+
coinbase = data[3].(common.Address)
|
| 1347 |
+
}
|
| 1348 |
+
|
| 1349 |
+
sequencedBatches := make([]SequencedBatch, len(sequences))
|
| 1350 |
+
for i, seq := range sequences {
|
| 1351 |
+
bn := lastBatchNumber - uint64(len(sequences)-(i+1))
|
| 1352 |
+
s := seq
|
| 1353 |
+
batch := SequencedBatch{
|
| 1354 |
+
BatchNumber: bn,
|
| 1355 |
+
L1InfoRoot: &l1InfoRoot,
|
| 1356 |
+
SequencerAddr: sequencer,
|
| 1357 |
+
TxHash: txHash,
|
| 1358 |
+
Nonce: nonce,
|
| 1359 |
+
Coinbase: coinbase,
|
| 1360 |
+
PolygonRollupBaseEtrogBatchData: &s,
|
| 1361 |
+
}
|
| 1362 |
+
if forkID >= state.FORKID_ELDERBERRY {
|
| 1363 |
+
batch.SequencedBatchElderberryData = &SequencedBatchElderberryData{
|
| 1364 |
+
MaxSequenceTimestamp: maxSequenceTimestamp,
|
| 1365 |
+
InitSequencedBatchNumber: initSequencedBatchNumber,
|
| 1366 |
+
}
|
| 1367 |
+
}
|
| 1368 |
+
sequencedBatches[i] = batch
|
| 1369 |
+
}
|
| 1370 |
+
|
| 1371 |
+
return sequencedBatches, nil
|
| 1372 |
+
case "sequenceBatchesValidium":
|
| 1373 |
+
var (
|
| 1374 |
+
sequencesValidium []polygonzkevm.PolygonValidiumEtrogValidiumBatchData
|
| 1375 |
+
dataAvailabilityMsg []byte
|
| 1376 |
+
)
|
| 1377 |
+
err := json.Unmarshal(bytedata, &sequencesValidium)
|
| 1378 |
+
if err != nil {
|
| 1379 |
+
return nil, err
|
| 1380 |
+
}
|
| 1381 |
+
|
| 1382 |
+
switch forkID {
|
| 1383 |
+
case state.FORKID_ETROG:
|
| 1384 |
+
coinbase = data[1].(common.Address)
|
| 1385 |
+
dataAvailabilityMsg = data[2].([]byte)
|
| 1386 |
+
|
| 1387 |
+
case state.FORKID_ELDERBERRY:
|
| 1388 |
+
maxSequenceTimestamp = data[1].(uint64)
|
| 1389 |
+
initSequencedBatchNumber = data[2].(uint64)
|
| 1390 |
+
coinbase = data[3].(common.Address)
|
| 1391 |
+
dataAvailabilityMsg = data[4].([]byte)
|
| 1392 |
+
}
|
| 1393 |
+
|
| 1394 |
+
// Pair the batch number, hash, and if it is forced. This will allow
|
| 1395 |
+
// retrieval from different sources, and keep them in original order.
|
| 1396 |
+
var batchInfos []batchInfo
|
| 1397 |
+
for i, d := range sequencesValidium {
|
| 1398 |
+
bn := lastBatchNumber - uint64(len(sequencesValidium)-(i+1))
|
| 1399 |
+
forced := d.ForcedTimestamp > 0
|
| 1400 |
+
h := d.TransactionsHash
|
| 1401 |
+
batchInfos = append(batchInfos, batchInfo{num: bn, hash: h, isForced: forced})
|
| 1402 |
+
}
|
| 1403 |
+
|
| 1404 |
+
batchData, err := retrieveBatchData(da, st, batchInfos, dataAvailabilityMsg)
|
| 1405 |
+
if err != nil {
|
| 1406 |
+
return nil, err
|
| 1407 |
+
}
|
| 1408 |
+
|
| 1409 |
+
sequencedBatches := make([]SequencedBatch, len(sequencesValidium))
|
| 1410 |
+
for i, info := range batchInfos {
|
| 1411 |
+
bn := info.num
|
| 1412 |
+
s := polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 1413 |
+
Transactions: batchData[i],
|
| 1414 |
+
ForcedGlobalExitRoot: sequencesValidium[i].ForcedGlobalExitRoot,
|
| 1415 |
+
ForcedTimestamp: sequencesValidium[i].ForcedTimestamp,
|
| 1416 |
+
ForcedBlockHashL1: sequencesValidium[i].ForcedBlockHashL1,
|
| 1417 |
+
}
|
| 1418 |
+
batch := SequencedBatch{
|
| 1419 |
+
BatchNumber: bn,
|
| 1420 |
+
L1InfoRoot: &l1InfoRoot,
|
| 1421 |
+
SequencerAddr: sequencer,
|
| 1422 |
+
TxHash: txHash,
|
| 1423 |
+
Nonce: nonce,
|
| 1424 |
+
Coinbase: coinbase,
|
| 1425 |
+
PolygonRollupBaseEtrogBatchData: &s,
|
| 1426 |
+
}
|
| 1427 |
+
if forkID >= state.FORKID_ELDERBERRY {
|
| 1428 |
+
elderberry := &SequencedBatchElderberryData{
|
| 1429 |
+
MaxSequenceTimestamp: maxSequenceTimestamp,
|
| 1430 |
+
InitSequencedBatchNumber: initSequencedBatchNumber,
|
| 1431 |
+
}
|
| 1432 |
+
batch.SequencedBatchElderberryData = elderberry
|
| 1433 |
+
}
|
| 1434 |
+
sequencedBatches[i] = batch
|
| 1435 |
}
|
| 1436 |
+
|
| 1437 |
+
return sequencedBatches, nil
|
| 1438 |
}
|
| 1439 |
|
| 1440 |
+
return nil, fmt.Errorf("unexpected method called in sequence batches transaction: %s", method.RawName)
|
| 1441 |
}
|
| 1442 |
|
| 1443 |
+
type batchInfo struct {
|
| 1444 |
+
num uint64
|
| 1445 |
+
hash common.Hash
|
| 1446 |
+
isForced bool
|
| 1447 |
+
}
|
| 1448 |
+
|
| 1449 |
+
func retrieveBatchData(da dataavailability.BatchDataProvider, st stateProvider, batchInfos []batchInfo, daMessage []byte) ([][]byte, error) {
|
| 1450 |
+
validiumData, err := getBatchL2Data(da, batchInfos, daMessage)
|
| 1451 |
if err != nil {
|
| 1452 |
return nil, err
|
| 1453 |
}
|
| 1454 |
+
forcedData, err := getForcedBatchData(st, batchInfos)
|
|
|
|
|
|
|
| 1455 |
if err != nil {
|
| 1456 |
return nil, err
|
| 1457 |
}
|
| 1458 |
+
data := make([][]byte, len(batchInfos))
|
| 1459 |
+
for i, info := range batchInfos {
|
| 1460 |
+
bn := info.num
|
| 1461 |
+
if info.isForced {
|
| 1462 |
+
data[i] = forcedData[bn]
|
| 1463 |
+
} else {
|
| 1464 |
+
data[i] = validiumData[bn]
|
| 1465 |
+
}
|
| 1466 |
+
}
|
| 1467 |
+
return data, nil
|
| 1468 |
+
}
|
| 1469 |
|
| 1470 |
+
func getBatchL2Data(da dataavailability.BatchDataProvider, batchInfos []batchInfo, daMessage []byte) (map[uint64][]byte, error) {
|
| 1471 |
+
var batchNums []uint64
|
| 1472 |
+
var batchHashes []common.Hash
|
| 1473 |
+
for _, info := range batchInfos {
|
| 1474 |
+
if !info.isForced {
|
| 1475 |
+
batchNums = append(batchNums, info.num)
|
| 1476 |
+
batchHashes = append(batchHashes, info.hash)
|
| 1477 |
+
}
|
| 1478 |
}
|
| 1479 |
+
if len(batchNums) == 0 {
|
| 1480 |
+
return nil, nil
|
| 1481 |
+
}
|
| 1482 |
+
batchL2Data, err := da.GetBatchL2Data(batchNums, batchHashes, daMessage)
|
| 1483 |
if err != nil {
|
| 1484 |
return nil, err
|
| 1485 |
}
|
| 1486 |
+
if len(batchL2Data) != len(batchNums) {
|
| 1487 |
+
return nil,
|
| 1488 |
+
fmt.Errorf("failed to retrieve all batch data. Expected %d, got %d", len(batchNums), len(batchL2Data))
|
| 1489 |
+
}
|
| 1490 |
+
data := make(map[uint64][]byte)
|
| 1491 |
+
for i, bn := range batchNums {
|
| 1492 |
+
data[bn] = batchL2Data[i]
|
| 1493 |
+
}
|
| 1494 |
+
return data, nil
|
| 1495 |
+
}
|
| 1496 |
+
|
| 1497 |
+
func getForcedBatchData(st stateProvider, batchInfos []batchInfo) (map[uint64][]byte, error) {
|
| 1498 |
+
var batchNums []uint64
|
| 1499 |
+
var batchHashes []common.Hash
|
| 1500 |
+
for _, info := range batchInfos {
|
| 1501 |
+
if info.isForced {
|
| 1502 |
+
batchNums = append(batchNums, info.num)
|
| 1503 |
+
batchHashes = append(batchHashes, info.hash)
|
| 1504 |
+
}
|
| 1505 |
+
}
|
| 1506 |
+
if len(batchNums) == 0 {
|
| 1507 |
+
return nil, nil
|
| 1508 |
+
}
|
| 1509 |
+
data, err := st.GetForcedBatchDataByNumbers(context.Background(), batchNums, nil)
|
| 1510 |
if err != nil {
|
| 1511 |
return nil, err
|
| 1512 |
}
|
| 1513 |
+
|
| 1514 |
+
for i, bn := range batchNums {
|
| 1515 |
+
expectedHash := batchHashes[i]
|
| 1516 |
+
d, ok := data[bn]
|
| 1517 |
+
if !ok {
|
| 1518 |
+
return nil, fmt.Errorf("missing forced batch data for number %d", bn)
|
| 1519 |
+
}
|
| 1520 |
+
actualHash := crypto.Keccak256Hash(d)
|
| 1521 |
+
if actualHash != expectedHash {
|
| 1522 |
+
return nil, fmt.Errorf("got wrong hash for forced batch data number %d", bn)
|
|
|
|
|
|
|
|
|
|
| 1523 |
}
|
| 1524 |
}
|
| 1525 |
+
return data, nil
|
|
|
|
| 1526 |
}
|
| 1527 |
|
| 1528 |
func decodeSequencesPreEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64) ([]SequencedBatch, error) {
|
| 1529 |
// Extract coded txs.
|
| 1530 |
// Load contract ABI
|
| 1531 |
+
smcAbi, err := abi.JSON(strings.NewReader(oldpolygonzkevm.OldpolygonzkevmABI))
|
| 1532 |
if err != nil {
|
| 1533 |
return nil, err
|
| 1534 |
}
|
|
|
|
| 1544 |
if err != nil {
|
| 1545 |
return nil, err
|
| 1546 |
}
|
| 1547 |
+
var sequences []oldpolygonzkevm.PolygonZkEVMBatchData
|
| 1548 |
bytedata, err := json.Marshal(data[0])
|
| 1549 |
if err != nil {
|
| 1550 |
return nil, err
|
|
|
|
| 1571 |
return sequencedBatches, nil
|
| 1572 |
}
|
| 1573 |
|
| 1574 |
+
func (etherMan *Client) oldVerifyBatchesTrustedAggregatorEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1575 |
log.Debug("TrustedVerifyBatches event detected")
|
| 1576 |
+
var vb *oldpolygonzkevm.OldpolygonzkevmVerifyBatchesTrustedAggregator
|
| 1577 |
+
vb, err := etherMan.OldZkEVM.ParseVerifyBatchesTrustedAggregator(vLog)
|
| 1578 |
if err != nil {
|
| 1579 |
log.Error("error parsing TrustedVerifyBatches event. Error: ", err)
|
| 1580 |
return err
|
|
|
|
| 1584 |
|
| 1585 |
func (etherMan *Client) verifyBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1586 |
log.Debug("VerifyBatches event detected")
|
| 1587 |
+
vb, err := etherMan.ZkEVM.ParseVerifyBatches(vLog)
|
| 1588 |
if err != nil {
|
| 1589 |
log.Error("error parsing VerifyBatches event. Error: ", err)
|
| 1590 |
return err
|
|
|
|
| 1631 |
|
| 1632 |
func (etherMan *Client) forceSequencedBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1633 |
log.Debug("SequenceForceBatches event detect")
|
| 1634 |
+
fsb, err := etherMan.ZkEVM.ParseSequenceForceBatches(vLog)
|
| 1635 |
if err != nil {
|
| 1636 |
return err
|
| 1637 |
}
|
|
|
|
| 1680 |
func decodeSequencedForceBatches(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, block *types.Block, nonce uint64) ([]SequencedForceBatch, error) {
|
| 1681 |
// Extract coded txs.
|
| 1682 |
// Load contract ABI
|
| 1683 |
+
abi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI))
|
| 1684 |
if err != nil {
|
| 1685 |
return nil, err
|
| 1686 |
}
|
|
|
|
| 1697 |
return nil, err
|
| 1698 |
}
|
| 1699 |
|
| 1700 |
+
var forceBatches []polygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 1701 |
bytedata, err := json.Marshal(data[0])
|
| 1702 |
if err != nil {
|
| 1703 |
return nil, err
|
|
|
|
| 1761 |
|
| 1762 |
// GetLatestBatchNumber function allows to retrieve the latest proposed batch in the smc
|
| 1763 |
func (etherMan *Client) GetLatestBatchNumber() (uint64, error) {
|
| 1764 |
+
var latestBatchNum uint64
|
| 1765 |
+
rollupData, err := etherMan.RollupManager.RollupIDToRollupData(&bind.CallOpts{Pending: false}, etherMan.RollupID)
|
| 1766 |
if err != nil {
|
| 1767 |
+
log.Debug("error getting latestBatchNum from rollupManager. Trying old zkevm smc... Error: ", err)
|
| 1768 |
+
latestBatchNum, err = etherMan.OldZkEVM.LastBatchSequenced(&bind.CallOpts{Pending: false})
|
| 1769 |
+
if err != nil {
|
| 1770 |
+
return latestBatchNum, err
|
| 1771 |
+
}
|
| 1772 |
+
} else {
|
| 1773 |
+
latestBatchNum = rollupData.LastBatchSequenced
|
| 1774 |
}
|
| 1775 |
+
return latestBatchNum, nil
|
| 1776 |
}
|
| 1777 |
|
| 1778 |
// GetLatestBlockHeader gets the latest block header from the ethereum
|
|
|
|
| 1819 |
|
| 1820 |
// GetLatestVerifiedBatchNum gets latest verified batch from ethereum
|
| 1821 |
func (etherMan *Client) GetLatestVerifiedBatchNum() (uint64, error) {
|
| 1822 |
+
var lastVerifiedBatchNum uint64
|
| 1823 |
+
rollupData, err := etherMan.RollupManager.RollupIDToRollupData(&bind.CallOpts{Pending: false}, etherMan.RollupID)
|
| 1824 |
if err != nil {
|
| 1825 |
+
log.Debug("error getting lastVerifiedBatchNum from rollupManager. Trying old zkevm smc... Error: ", err)
|
| 1826 |
+
lastVerifiedBatchNum, err = etherMan.OldZkEVM.LastVerifiedBatch(&bind.CallOpts{Pending: false})
|
| 1827 |
+
if err != nil {
|
| 1828 |
+
return lastVerifiedBatchNum, err
|
| 1829 |
+
}
|
| 1830 |
+
} else {
|
| 1831 |
+
lastVerifiedBatchNum = rollupData.LastVerifiedBatch
|
| 1832 |
}
|
| 1833 |
+
return lastVerifiedBatchNum, nil
|
| 1834 |
}
|
| 1835 |
|
| 1836 |
// GetTx function get ethereum tx
|
|
|
|
| 1865 |
|
| 1866 |
// GetTrustedSequencerURL Gets the trusted sequencer url from rollup smc
|
| 1867 |
func (etherMan *Client) GetTrustedSequencerURL() (string, error) {
|
| 1868 |
+
url, err := etherMan.ZkEVM.TrustedSequencerURL(&bind.CallOpts{Pending: false})
|
| 1869 |
+
//TODO: remove this code because is for compatibility with oldZkEVM
|
| 1870 |
+
if err != nil || url == "" {
|
| 1871 |
+
// Getting from oldZkEVM Contract
|
| 1872 |
+
log.Debug("getting trusted sequencer URL from oldZkevm smc")
|
| 1873 |
+
return etherMan.OldZkEVM.TrustedSequencerURL(&bind.CallOpts{Pending: false})
|
| 1874 |
+
}
|
| 1875 |
+
// err is always nil
|
| 1876 |
+
return url, nil
|
| 1877 |
}
|
| 1878 |
|
| 1879 |
// GetL2ChainID returns L2 Chain ID
|
| 1880 |
func (etherMan *Client) GetL2ChainID() (uint64, error) {
|
| 1881 |
+
chainID, err := etherMan.OldZkEVM.ChainID(&bind.CallOpts{Pending: false})
|
| 1882 |
+
log.Debug("chainID read from oldZkevm: ", chainID)
|
| 1883 |
if err != nil || chainID == 0 {
|
| 1884 |
+
log.Debug("error from oldZkevm: ", err)
|
| 1885 |
+
rollupData, err := etherMan.RollupManager.RollupIDToRollupData(&bind.CallOpts{Pending: false}, etherMan.RollupID)
|
| 1886 |
+
log.Debugf("ChainID read from rollupManager: %d using rollupID: %d", rollupData.ChainID, etherMan.RollupID)
|
| 1887 |
if err != nil {
|
| 1888 |
+
log.Debug("error from rollupManager: ", err)
|
| 1889 |
return 0, err
|
| 1890 |
} else if rollupData.ChainID == 0 {
|
| 1891 |
return rollupData.ChainID, fmt.Errorf("error: chainID received is 0!!")
|
|
|
|
| 1916 |
return etherMan.EthClient.SendTransaction(ctx, tx)
|
| 1917 |
}
|
| 1918 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1919 |
// CurrentNonce returns the current nonce for the provided account
|
| 1920 |
func (etherMan *Client) CurrentNonce(ctx context.Context, account common.Address) (uint64, error) {
|
| 1921 |
return etherMan.EthClient.NonceAt(ctx, account, nil)
|
|
|
|
| 1948 |
opts.BlockNumber = new(big.Int).SetUint64(*blockNumber)
|
| 1949 |
}
|
| 1950 |
|
| 1951 |
+
return etherman.GlobalExitRootManager.DepositCount(opts)
|
| 1952 |
}
|
| 1953 |
|
| 1954 |
// CheckTxWasMined check if a tx was already mined
|
|
|
|
| 2005 |
}
|
| 2006 |
|
| 2007 |
// LoadAuthFromKeyStore loads an authorization from a key store file
|
| 2008 |
+
func (etherMan *Client) LoadAuthFromKeyStore(path, password string) (*bind.TransactOpts, *ecdsa.PrivateKey, error) {
|
| 2009 |
+
auth, pk, err := newAuthFromKeystore(path, password, etherMan.l1Cfg.L1ChainID)
|
| 2010 |
if err != nil {
|
| 2011 |
+
return nil, nil, err
|
| 2012 |
}
|
| 2013 |
|
| 2014 |
log.Infof("loaded authorization for address: %v", auth.From.String())
|
| 2015 |
etherMan.auth[auth.From] = auth
|
| 2016 |
+
return &auth, pk, nil
|
| 2017 |
}
|
| 2018 |
|
| 2019 |
// newKeyFromKeystore creates an instance of a keystore key from a keystore file
|
|
|
|
| 2034 |
}
|
| 2035 |
|
| 2036 |
// newAuthFromKeystore an authorization instance from a keystore file
|
| 2037 |
+
func newAuthFromKeystore(path, password string, chainID uint64) (bind.TransactOpts, *ecdsa.PrivateKey, error) {
|
| 2038 |
log.Infof("reading key from: %v", path)
|
| 2039 |
key, err := newKeyFromKeystore(path, password)
|
| 2040 |
if err != nil {
|
| 2041 |
+
return bind.TransactOpts{}, nil, err
|
| 2042 |
}
|
| 2043 |
if key == nil {
|
| 2044 |
+
return bind.TransactOpts{}, nil, nil
|
| 2045 |
}
|
| 2046 |
auth, err := bind.NewKeyedTransactorWithChainID(key.PrivateKey, new(big.Int).SetUint64(chainID))
|
| 2047 |
if err != nil {
|
| 2048 |
+
return bind.TransactOpts{}, nil, err
|
| 2049 |
}
|
| 2050 |
+
return *auth, key.PrivateKey, nil
|
| 2051 |
}
|
| 2052 |
|
| 2053 |
// getAuthByAddress tries to get an authorization from the authorizations map
|
|
|
|
| 2075 |
|
| 2076 |
return *auth, nil
|
| 2077 |
}
|
| 2078 |
+
|
| 2079 |
+
// GetDAProtocolAddr returns the address of the data availability protocol
|
| 2080 |
+
func (etherMan *Client) GetDAProtocolAddr() (common.Address, error) {
|
| 2081 |
+
return etherMan.ZkEVM.DataAvailabilityProtocol(&bind.CallOpts{Pending: false})
|
| 2082 |
+
}
|
| 2083 |
+
|
| 2084 |
+
// GetDAProtocolName returns the name of the data availability protocol
|
| 2085 |
+
func (etherMan *Client) GetDAProtocolName() (string, error) {
|
| 2086 |
+
return etherMan.DAProtocol.GetProcotolName(&bind.CallOpts{Pending: false})
|
| 2087 |
+
}
|
| 2088 |
+
|
| 2089 |
+
// SetDataAvailabilityProtocol sets the address for the new data availability protocol
|
| 2090 |
+
func (etherMan *Client) SetDataAvailabilityProtocol(from, daAddress common.Address) (*types.Transaction, error) {
|
| 2091 |
+
auth, err := etherMan.getAuthByAddress(from)
|
| 2092 |
+
if err != nil {
|
| 2093 |
+
return nil, err
|
| 2094 |
+
}
|
| 2095 |
+
|
| 2096 |
+
return etherMan.ZkEVM.SetDataAvailabilityProtocol(&auth, daAddress)
|
| 2097 |
+
}
|
| 2098 |
+
|
| 2099 |
+
// GetRollupId returns the rollup id
|
| 2100 |
+
func (etherMan *Client) GetRollupId() uint32 {
|
| 2101 |
+
return etherMan.RollupID
|
| 2102 |
+
}
|
|
@@ -38,7 +38,7 @@
|
|
| 38 |
}
|
| 39 |
|
| 40 |
// This function prepare the blockchain, the wallet with funds and deploy the smc
|
| 41 |
-
func newTestingEnv() (ethman *Client, ethBackend *simulated.Backend, auth *bind.TransactOpts, polAddr common.Address, br *
|
| 42 |
privateKey, err := crypto.GenerateKey()
|
| 43 |
if err != nil {
|
| 44 |
log.Fatal(err)
|
|
@@ -47,7 +47,9 @@
|
|
| 47 |
if err != nil {
|
| 48 |
log.Fatal(err)
|
| 49 |
}
|
| 50 |
-
|
|
|
|
|
|
|
| 51 |
if err != nil {
|
| 52 |
log.Fatal(err)
|
| 53 |
}
|
|
@@ -55,12 +57,12 @@
|
|
| 55 |
if err != nil {
|
| 56 |
log.Fatal(err)
|
| 57 |
}
|
| 58 |
-
return ethman, ethBackend, auth, polAddr, br
|
| 59 |
}
|
| 60 |
|
| 61 |
func TestGEREvent(t *testing.T) {
|
| 62 |
// Set up testing environment
|
| 63 |
-
etherman, ethBackend, auth, _, br := newTestingEnv()
|
| 64 |
|
| 65 |
// Read currentBlock
|
| 66 |
ctx := context.Background()
|
|
@@ -82,26 +84,26 @@
|
|
| 82 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 83 |
require.NoError(t, err)
|
| 84 |
t.Logf("Blocks: %+v", blocks)
|
| 85 |
-
assert.Equal(t, uint64(
|
| 86 |
assert.NotEqual(t, common.Hash{}, blocks[0].L1InfoTree[0].MainnetExitRoot)
|
| 87 |
assert.Equal(t, common.Hash{}, blocks[0].L1InfoTree[0].RollupExitRoot)
|
| 88 |
}
|
| 89 |
|
| 90 |
func TestForcedBatchEvent(t *testing.T) {
|
| 91 |
// Set up testing environment
|
| 92 |
-
etherman, ethBackend, auth, _, _ := newTestingEnv()
|
| 93 |
|
| 94 |
// Read currentBlock
|
| 95 |
ctx := context.Background()
|
| 96 |
initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
|
| 97 |
require.NoError(t, err)
|
| 98 |
|
| 99 |
-
amount, err := etherman.
|
| 100 |
require.NoError(t, err)
|
| 101 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 102 |
data, err := hex.DecodeString(rawTxs)
|
| 103 |
require.NoError(t, err)
|
| 104 |
-
_, err = etherman.
|
| 105 |
require.NoError(t, err)
|
| 106 |
|
| 107 |
// Mine the tx in a block
|
|
@@ -114,8 +116,8 @@
|
|
| 114 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 115 |
require.NoError(t, err)
|
| 116 |
t.Logf("Blocks: %+v", blocks)
|
| 117 |
-
assert.Equal(t, uint64(
|
| 118 |
-
assert.Equal(t, uint64(
|
| 119 |
assert.NotEqual(t, common.Hash{}, blocks[0].ForcedBatches[0].GlobalExitRoot)
|
| 120 |
assert.NotEqual(t, time.Time{}, blocks[0].ForcedBatches[0].ForcedAt)
|
| 121 |
assert.Equal(t, uint64(1), blocks[0].ForcedBatches[0].ForcedBatchNumber)
|
|
@@ -125,7 +127,7 @@
|
|
| 125 |
|
| 126 |
func TestSequencedBatchesEvent(t *testing.T) {
|
| 127 |
// Set up testing environment
|
| 128 |
-
etherman, ethBackend, auth, _, br := newTestingEnv()
|
| 129 |
|
| 130 |
// Read currentBlock
|
| 131 |
ctx := context.Background()
|
|
@@ -139,12 +141,12 @@
|
|
| 139 |
ethBackend.Commit()
|
| 140 |
auth.Value = big.NewInt(0)
|
| 141 |
|
| 142 |
-
amount, err := etherman.
|
| 143 |
require.NoError(t, err)
|
| 144 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 145 |
data, err := hex.DecodeString(rawTxs)
|
| 146 |
require.NoError(t, err)
|
| 147 |
-
_, err = etherman.
|
| 148 |
require.NoError(t, err)
|
| 149 |
require.NoError(t, err)
|
| 150 |
ethBackend.Commit()
|
|
@@ -156,13 +158,19 @@
|
|
| 156 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), ¤tBlockNumber)
|
| 157 |
require.NoError(t, err)
|
| 158 |
t.Log("Blocks: ", blocks)
|
| 159 |
-
var sequences []
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
|
|
|
| 164 |
})
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
require.NoError(t, err)
|
| 167 |
|
| 168 |
// Mine the tx in a block
|
|
@@ -188,7 +196,7 @@
|
|
| 188 |
|
| 189 |
func TestVerifyBatchEvent(t *testing.T) {
|
| 190 |
// Set up testing environment
|
| 191 |
-
etherman, ethBackend, auth, _, _ := newTestingEnv()
|
| 192 |
|
| 193 |
// Read currentBlock
|
| 194 |
ctx := context.Background()
|
|
@@ -197,17 +205,18 @@
|
|
| 197 |
require.NoError(t, err)
|
| 198 |
|
| 199 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 200 |
-
tx :=
|
| 201 |
-
|
| 202 |
}
|
| 203 |
-
|
| 204 |
-
_, err = etherman.
|
| 205 |
require.NoError(t, err)
|
|
|
|
| 206 |
|
| 207 |
// Mine the tx in a block
|
| 208 |
ethBackend.Commit()
|
| 209 |
|
| 210 |
-
_, err = etherman.
|
| 211 |
require.NoError(t, err)
|
| 212 |
|
| 213 |
// Mine the tx in a block
|
|
@@ -220,7 +229,7 @@
|
|
| 220 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 221 |
require.NoError(t, err)
|
| 222 |
t.Logf("Blocks: %+v, \nOrder: %+v", blocks, order)
|
| 223 |
-
assert.Equal(t, uint64(
|
| 224 |
assert.Equal(t, uint64(1), blocks[1].VerifiedBatches[0].BatchNumber)
|
| 225 |
assert.NotEqual(t, common.Address{}, blocks[1].VerifiedBatches[0].Aggregator)
|
| 226 |
assert.NotEqual(t, common.Hash{}, blocks[1].VerifiedBatches[0].TxHash)
|
|
@@ -232,19 +241,19 @@
|
|
| 232 |
|
| 233 |
func TestSequenceForceBatchesEvent(t *testing.T) {
|
| 234 |
// Set up testing environment
|
| 235 |
-
etherman, ethBackend, auth, _, _ := newTestingEnv()
|
| 236 |
|
| 237 |
// Read currentBlock
|
| 238 |
ctx := context.Background()
|
| 239 |
initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
|
| 240 |
require.NoError(t, err)
|
| 241 |
|
| 242 |
-
amount, err := etherman.
|
| 243 |
require.NoError(t, err)
|
| 244 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 245 |
data, err := hex.DecodeString(rawTxs)
|
| 246 |
require.NoError(t, err)
|
| 247 |
-
_, err = etherman.
|
| 248 |
require.NoError(t, err)
|
| 249 |
ethBackend.Commit()
|
| 250 |
ethBackend.Commit()
|
|
@@ -266,13 +275,13 @@
|
|
| 266 |
prevBlock, err := etherman.EthClient.BlockByNumber(ctx, big.NewInt(0).SetUint64(blocks[0].BlockNumber-1))
|
| 267 |
require.NoError(t, err)
|
| 268 |
forcedBlockHashL1 := prevBlock.Hash()
|
| 269 |
-
forceBatchData :=
|
| 270 |
Transactions: blocks[0].ForcedBatches[0].RawTxsData,
|
| 271 |
ForcedGlobalExitRoot: forcedGer,
|
| 272 |
ForcedTimestamp: forcedTimestamp,
|
| 273 |
ForcedBlockHashL1: forcedBlockHashL1,
|
| 274 |
}
|
| 275 |
-
_, err = etherman.
|
| 276 |
require.NoError(t, err)
|
| 277 |
ethBackend.Commit()
|
| 278 |
|
|
@@ -283,7 +292,7 @@
|
|
| 283 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 284 |
require.NoError(t, err)
|
| 285 |
t.Logf("Blocks: %+v", blocks)
|
| 286 |
-
assert.Equal(t, uint64(
|
| 287 |
assert.Equal(t, uint64(2), blocks[1].SequencedForceBatches[0][0].BatchNumber)
|
| 288 |
assert.Equal(t, forcedGer, common.BytesToHash(blocks[1].SequencedForceBatches[0][0].ForcedGlobalExitRoot[:]))
|
| 289 |
assert.Equal(t, forcedTimestamp, blocks[1].SequencedForceBatches[0][0].ForcedTimestamp)
|
|
@@ -293,7 +302,7 @@
|
|
| 293 |
|
| 294 |
func TestSendSequences(t *testing.T) {
|
| 295 |
// Set up testing environment
|
| 296 |
-
etherman, ethBackend, auth, _, br := newTestingEnv()
|
| 297 |
|
| 298 |
// Read currentBlock
|
| 299 |
ctx := context.Background()
|
|
@@ -315,10 +324,12 @@
|
|
| 315 |
BatchL2Data: batchL2Data,
|
| 316 |
LastL2BLockTimestamp: time.Now().Unix(),
|
| 317 |
}
|
|
|
|
| 318 |
lastL2BlockTStamp := tx1.Time().Unix()
|
| 319 |
-
|
| 320 |
-
tx, err := etherman.sequenceBatches(*auth, []ethmanTypes.Sequence{sequence}, uint64(lastL2BlockTStamp), uint64(1), auth.From)
|
| 321 |
require.NoError(t, err)
|
|
|
|
|
|
|
| 322 |
log.Debug("TX: ", tx.Hash())
|
| 323 |
ethBackend.Commit()
|
| 324 |
|
|
@@ -341,7 +352,7 @@
|
|
| 341 |
|
| 342 |
func TestGasPrice(t *testing.T) {
|
| 343 |
// Set up testing environment
|
| 344 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 345 |
etherscanM := new(etherscanMock)
|
| 346 |
ethGasStationM := new(ethGasStationMock)
|
| 347 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
@@ -360,14 +371,14 @@
|
|
| 360 |
|
| 361 |
func TestErrorEthGasStationPrice(t *testing.T) {
|
| 362 |
// Set up testing environment
|
| 363 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 364 |
ethGasStationM := new(ethGasStationMock)
|
| 365 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, ethGasStationM}
|
| 366 |
ctx := context.Background()
|
| 367 |
|
| 368 |
ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from ethGasStation"))
|
| 369 |
gp := etherman.GetL1GasPrice(ctx)
|
| 370 |
-
assert.Equal(t, big.NewInt(
|
| 371 |
|
| 372 |
etherscanM := new(etherscanMock)
|
| 373 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
@@ -379,7 +390,7 @@
|
|
| 379 |
|
| 380 |
func TestErrorEtherScanPrice(t *testing.T) {
|
| 381 |
// Set up testing environment
|
| 382 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 383 |
etherscanM := new(etherscanMock)
|
| 384 |
ethGasStationM := new(ethGasStationMock)
|
| 385 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
@@ -393,7 +404,7 @@
|
|
| 393 |
|
| 394 |
func TestGetForks(t *testing.T) {
|
| 395 |
// Set up testing environment
|
| 396 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 397 |
ctx := context.Background()
|
| 398 |
forks, err := etherman.GetForks(ctx, 0, 132)
|
| 399 |
require.NoError(t, err)
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
// This function prepare the blockchain, the wallet with funds and deploy the smc
|
| 41 |
+
func newTestingEnv(t *testing.T) (ethman *Client, ethBackend *simulated.Backend, auth *bind.TransactOpts, polAddr common.Address, br *polygonzkevmbridge.Polygonzkevmbridge, da *daMock, st *stateMock) {
|
| 42 |
privateKey, err := crypto.GenerateKey()
|
| 43 |
if err != nil {
|
| 44 |
log.Fatal(err)
|
|
|
|
| 47 |
if err != nil {
|
| 48 |
log.Fatal(err)
|
| 49 |
}
|
| 50 |
+
da = newDaMock(t)
|
| 51 |
+
st = newStateMock(t)
|
| 52 |
+
ethman, ethBackend, polAddr, br, err = NewSimulatedEtherman(Config{ForkIDChunkSize: 10}, auth, da, st)
|
| 53 |
if err != nil {
|
| 54 |
log.Fatal(err)
|
| 55 |
}
|
|
|
|
| 57 |
if err != nil {
|
| 58 |
log.Fatal(err)
|
| 59 |
}
|
| 60 |
+
return ethman, ethBackend, auth, polAddr, br, da, st
|
| 61 |
}
|
| 62 |
|
| 63 |
func TestGEREvent(t *testing.T) {
|
| 64 |
// Set up testing environment
|
| 65 |
+
etherman, ethBackend, auth, _, br, _, _ := newTestingEnv(t)
|
| 66 |
|
| 67 |
// Read currentBlock
|
| 68 |
ctx := context.Background()
|
|
|
|
| 84 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 85 |
require.NoError(t, err)
|
| 86 |
t.Logf("Blocks: %+v", blocks)
|
| 87 |
+
assert.Equal(t, uint64(11), blocks[0].L1InfoTree[0].BlockNumber)
|
| 88 |
assert.NotEqual(t, common.Hash{}, blocks[0].L1InfoTree[0].MainnetExitRoot)
|
| 89 |
assert.Equal(t, common.Hash{}, blocks[0].L1InfoTree[0].RollupExitRoot)
|
| 90 |
}
|
| 91 |
|
| 92 |
func TestForcedBatchEvent(t *testing.T) {
|
| 93 |
// Set up testing environment
|
| 94 |
+
etherman, ethBackend, auth, _, _, _, _ := newTestingEnv(t)
|
| 95 |
|
| 96 |
// Read currentBlock
|
| 97 |
ctx := context.Background()
|
| 98 |
initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
|
| 99 |
require.NoError(t, err)
|
| 100 |
|
| 101 |
+
amount, err := etherman.RollupManager.GetForcedBatchFee(&bind.CallOpts{Pending: false})
|
| 102 |
require.NoError(t, err)
|
| 103 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 104 |
data, err := hex.DecodeString(rawTxs)
|
| 105 |
require.NoError(t, err)
|
| 106 |
+
_, err = etherman.ZkEVM.ForceBatch(auth, data, amount)
|
| 107 |
require.NoError(t, err)
|
| 108 |
|
| 109 |
// Mine the tx in a block
|
|
|
|
| 116 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 117 |
require.NoError(t, err)
|
| 118 |
t.Logf("Blocks: %+v", blocks)
|
| 119 |
+
assert.Equal(t, uint64(11), blocks[0].BlockNumber)
|
| 120 |
+
assert.Equal(t, uint64(11), blocks[0].ForcedBatches[0].BlockNumber)
|
| 121 |
assert.NotEqual(t, common.Hash{}, blocks[0].ForcedBatches[0].GlobalExitRoot)
|
| 122 |
assert.NotEqual(t, time.Time{}, blocks[0].ForcedBatches[0].ForcedAt)
|
| 123 |
assert.Equal(t, uint64(1), blocks[0].ForcedBatches[0].ForcedBatchNumber)
|
|
|
|
| 127 |
|
| 128 |
func TestSequencedBatchesEvent(t *testing.T) {
|
| 129 |
// Set up testing environment
|
| 130 |
+
etherman, ethBackend, auth, _, br, da, _ := newTestingEnv(t)
|
| 131 |
|
| 132 |
// Read currentBlock
|
| 133 |
ctx := context.Background()
|
|
|
|
| 141 |
ethBackend.Commit()
|
| 142 |
auth.Value = big.NewInt(0)
|
| 143 |
|
| 144 |
+
amount, err := etherman.RollupManager.GetForcedBatchFee(&bind.CallOpts{Pending: false})
|
| 145 |
require.NoError(t, err)
|
| 146 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 147 |
data, err := hex.DecodeString(rawTxs)
|
| 148 |
require.NoError(t, err)
|
| 149 |
+
_, err = etherman.ZkEVM.ForceBatch(auth, data, amount)
|
| 150 |
require.NoError(t, err)
|
| 151 |
require.NoError(t, err)
|
| 152 |
ethBackend.Commit()
|
|
|
|
| 158 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), ¤tBlockNumber)
|
| 159 |
require.NoError(t, err)
|
| 160 |
t.Log("Blocks: ", blocks)
|
| 161 |
+
var sequences []polygonzkevm.PolygonValidiumEtrogValidiumBatchData
|
| 162 |
+
txsHash := crypto.Keccak256Hash(common.Hex2Bytes(rawTxs))
|
| 163 |
+
sequences = append(sequences, polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 164 |
+
TransactionsHash: txsHash,
|
| 165 |
+
}, polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 166 |
+
TransactionsHash: txsHash,
|
| 167 |
})
|
| 168 |
+
batchNums := []uint64{2, 3}
|
| 169 |
+
batchHashes := []common.Hash{txsHash, txsHash}
|
| 170 |
+
batchData := [][]byte{data, data}
|
| 171 |
+
daMessage, _ := hex.DecodeString("0x123456789123456789")
|
| 172 |
+
da.Mock.On("GetBatchL2Data", batchNums, batchHashes, daMessage).Return(batchData, nil)
|
| 173 |
+
_, err = etherman.ZkEVM.SequenceBatchesValidium(auth, sequences, uint64(time.Now().Unix()), uint64(1), auth.From, daMessage)
|
| 174 |
require.NoError(t, err)
|
| 175 |
|
| 176 |
// Mine the tx in a block
|
|
|
|
| 196 |
|
| 197 |
func TestVerifyBatchEvent(t *testing.T) {
|
| 198 |
// Set up testing environment
|
| 199 |
+
etherman, ethBackend, auth, _, _, da, _ := newTestingEnv(t)
|
| 200 |
|
| 201 |
// Read currentBlock
|
| 202 |
ctx := context.Background()
|
|
|
|
| 205 |
require.NoError(t, err)
|
| 206 |
|
| 207 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 208 |
+
tx := polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 209 |
+
TransactionsHash: crypto.Keccak256Hash(common.Hex2Bytes(rawTxs)),
|
| 210 |
}
|
| 211 |
+
daMessage, _ := hex.DecodeString("0x1234")
|
| 212 |
+
_, err = etherman.ZkEVM.SequenceBatchesValidium(auth, []polygonzkevm.PolygonValidiumEtrogValidiumBatchData{tx}, uint64(time.Now().Unix()), uint64(1), auth.From, daMessage)
|
| 213 |
require.NoError(t, err)
|
| 214 |
+
da.Mock.On("GetBatchL2Data", []uint64{2}, []common.Hash{crypto.Keccak256Hash(common.Hex2Bytes(rawTxs))}, daMessage).Return([][]byte{common.Hex2Bytes(rawTxs)}, nil)
|
| 215 |
|
| 216 |
// Mine the tx in a block
|
| 217 |
ethBackend.Commit()
|
| 218 |
|
| 219 |
+
_, err = etherman.RollupManager.VerifyBatchesTrustedAggregator(auth, 1, uint64(0), uint64(0), uint64(1), [32]byte{}, [32]byte{}, auth.From, [24][32]byte{})
|
| 220 |
require.NoError(t, err)
|
| 221 |
|
| 222 |
// Mine the tx in a block
|
|
|
|
| 229 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 230 |
require.NoError(t, err)
|
| 231 |
t.Logf("Blocks: %+v, \nOrder: %+v", blocks, order)
|
| 232 |
+
assert.Equal(t, uint64(12), blocks[1].BlockNumber)
|
| 233 |
assert.Equal(t, uint64(1), blocks[1].VerifiedBatches[0].BatchNumber)
|
| 234 |
assert.NotEqual(t, common.Address{}, blocks[1].VerifiedBatches[0].Aggregator)
|
| 235 |
assert.NotEqual(t, common.Hash{}, blocks[1].VerifiedBatches[0].TxHash)
|
|
|
|
| 241 |
|
| 242 |
func TestSequenceForceBatchesEvent(t *testing.T) {
|
| 243 |
// Set up testing environment
|
| 244 |
+
etherman, ethBackend, auth, _, _, _, _ := newTestingEnv(t)
|
| 245 |
|
| 246 |
// Read currentBlock
|
| 247 |
ctx := context.Background()
|
| 248 |
initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
|
| 249 |
require.NoError(t, err)
|
| 250 |
|
| 251 |
+
amount, err := etherman.RollupManager.GetForcedBatchFee(&bind.CallOpts{Pending: false})
|
| 252 |
require.NoError(t, err)
|
| 253 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 254 |
data, err := hex.DecodeString(rawTxs)
|
| 255 |
require.NoError(t, err)
|
| 256 |
+
_, err = etherman.ZkEVM.ForceBatch(auth, data, amount)
|
| 257 |
require.NoError(t, err)
|
| 258 |
ethBackend.Commit()
|
| 259 |
ethBackend.Commit()
|
|
|
|
| 275 |
prevBlock, err := etherman.EthClient.BlockByNumber(ctx, big.NewInt(0).SetUint64(blocks[0].BlockNumber-1))
|
| 276 |
require.NoError(t, err)
|
| 277 |
forcedBlockHashL1 := prevBlock.Hash()
|
| 278 |
+
forceBatchData := polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 279 |
Transactions: blocks[0].ForcedBatches[0].RawTxsData,
|
| 280 |
ForcedGlobalExitRoot: forcedGer,
|
| 281 |
ForcedTimestamp: forcedTimestamp,
|
| 282 |
ForcedBlockHashL1: forcedBlockHashL1,
|
| 283 |
}
|
| 284 |
+
_, err = etherman.ZkEVM.SequenceForceBatches(auth, []polygonzkevm.PolygonRollupBaseEtrogBatchData{forceBatchData})
|
| 285 |
require.NoError(t, err)
|
| 286 |
ethBackend.Commit()
|
| 287 |
|
|
|
|
| 292 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 293 |
require.NoError(t, err)
|
| 294 |
t.Logf("Blocks: %+v", blocks)
|
| 295 |
+
assert.Equal(t, uint64(15), blocks[1].BlockNumber)
|
| 296 |
assert.Equal(t, uint64(2), blocks[1].SequencedForceBatches[0][0].BatchNumber)
|
| 297 |
assert.Equal(t, forcedGer, common.BytesToHash(blocks[1].SequencedForceBatches[0][0].ForcedGlobalExitRoot[:]))
|
| 298 |
assert.Equal(t, forcedTimestamp, blocks[1].SequencedForceBatches[0][0].ForcedTimestamp)
|
|
|
|
| 302 |
|
| 303 |
func TestSendSequences(t *testing.T) {
|
| 304 |
// Set up testing environment
|
| 305 |
+
etherman, ethBackend, auth, _, br, da, _ := newTestingEnv(t)
|
| 306 |
|
| 307 |
// Read currentBlock
|
| 308 |
ctx := context.Background()
|
|
|
|
| 324 |
BatchL2Data: batchL2Data,
|
| 325 |
LastL2BLockTimestamp: time.Now().Unix(),
|
| 326 |
}
|
| 327 |
+
daMessage, _ := hex.DecodeString("0x1234")
|
| 328 |
lastL2BlockTStamp := tx1.Time().Unix()
|
| 329 |
+
tx, err := etherman.sequenceBatches(*auth, []ethmanTypes.Sequence{sequence}, uint64(lastL2BlockTStamp), uint64(1), auth.From, daMessage)
|
|
|
|
| 330 |
require.NoError(t, err)
|
| 331 |
+
da.Mock.On("GetBatchL2Data", []uint64{2}, []common.Hash{crypto.Keccak256Hash(batchL2Data)}, daMessage).Return([][]byte{batchL2Data}, nil)
|
| 332 |
+
|
| 333 |
log.Debug("TX: ", tx.Hash())
|
| 334 |
ethBackend.Commit()
|
| 335 |
|
|
|
|
| 352 |
|
| 353 |
func TestGasPrice(t *testing.T) {
|
| 354 |
// Set up testing environment
|
| 355 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 356 |
etherscanM := new(etherscanMock)
|
| 357 |
ethGasStationM := new(ethGasStationMock)
|
| 358 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
|
|
| 371 |
|
| 372 |
func TestErrorEthGasStationPrice(t *testing.T) {
|
| 373 |
// Set up testing environment
|
| 374 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 375 |
ethGasStationM := new(ethGasStationMock)
|
| 376 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, ethGasStationM}
|
| 377 |
ctx := context.Background()
|
| 378 |
|
| 379 |
ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from ethGasStation"))
|
| 380 |
gp := etherman.GetL1GasPrice(ctx)
|
| 381 |
+
assert.Equal(t, big.NewInt(1263075579), gp)
|
| 382 |
|
| 383 |
etherscanM := new(etherscanMock)
|
| 384 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
|
|
| 390 |
|
| 391 |
func TestErrorEtherScanPrice(t *testing.T) {
|
| 392 |
// Set up testing environment
|
| 393 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 394 |
etherscanM := new(etherscanMock)
|
| 395 |
ethGasStationM := new(ethGasStationMock)
|
| 396 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
|
|
| 404 |
|
| 405 |
func TestGetForks(t *testing.T) {
|
| 406 |
// Set up testing environment
|
| 407 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 408 |
ctx := context.Background()
|
| 409 |
forks, err := etherman.GetForks(ctx, 0, 132)
|
| 410 |
require.NoError(t, err)
|
|
@@ -1,191 +0,0 @@
|
|
| 1 |
-
package etherman
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"bytes"
|
| 5 |
-
"context"
|
| 6 |
-
"fmt"
|
| 7 |
-
"math/big"
|
| 8 |
-
|
| 9 |
-
"github.com/ethereum/go-ethereum"
|
| 10 |
-
"github.com/ethereum/go-ethereum/common"
|
| 11 |
-
"github.com/ethereum/go-ethereum/core"
|
| 12 |
-
"github.com/ethereum/go-ethereum/core/types"
|
| 13 |
-
)
|
| 14 |
-
|
| 15 |
-
// BlockRetriever is the interface required from etherman main object
|
| 16 |
-
type BlockRetriever interface {
|
| 17 |
-
RetrieveFullBlockForEvent(ctx context.Context, vLog types.Log) (*Block, error)
|
| 18 |
-
}
|
| 19 |
-
|
| 20 |
-
// GenericEventProcessor is the interface that a processor must implement
|
| 21 |
-
type GenericEventProcessor interface {
|
| 22 |
-
// EventSignature returns the signature of the event supported
|
| 23 |
-
// evaluate if make sens to support multiples signatures
|
| 24 |
-
EventSignature() common.Hash
|
| 25 |
-
AddEventDataToBlock(ctx context.Context, vLog types.Log, block *Block, callData *CallData) (*Order, error)
|
| 26 |
-
}
|
| 27 |
-
|
| 28 |
-
// CallDataExtractor is the interface required to extract the call data from a transaction
|
| 29 |
-
type CallDataExtractor interface {
|
| 30 |
-
ExtractCallData(ctx context.Context, blockHash, txHash common.Hash, txIndex uint) (*CallData, error)
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
// EventManager is a struct that manages the L1 events
|
| 34 |
-
// The way of using this is create and add Processor
|
| 35 |
-
// A processor only need to code the specific part of adding specific data
|
| 36 |
-
// to the block
|
| 37 |
-
type EventManager struct {
|
| 38 |
-
blockRetriever BlockRetriever
|
| 39 |
-
callDataExtractor CallDataExtractor
|
| 40 |
-
|
| 41 |
-
processors []GenericEventProcessor
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
// NewEventManager creates a new EventManager
|
| 45 |
-
func NewEventManager(blockRetriever BlockRetriever, callDataExtractor CallDataExtractor) *EventManager {
|
| 46 |
-
return &EventManager{
|
| 47 |
-
blockRetriever: blockRetriever,
|
| 48 |
-
callDataExtractor: callDataExtractor,
|
| 49 |
-
processors: []GenericEventProcessor{},
|
| 50 |
-
}
|
| 51 |
-
}
|
| 52 |
-
|
| 53 |
-
// AddProcessor adds a new processor to the EventManager
|
| 54 |
-
func (e *EventManager) AddProcessor(processor GenericEventProcessor) {
|
| 55 |
-
e.processors = append(e.processors, processor)
|
| 56 |
-
}
|
| 57 |
-
|
| 58 |
-
// ProcessEvent processes an event
|
| 59 |
-
// this is the interface with etherman
|
| 60 |
-
// it returns true if this event belong to this processor
|
| 61 |
-
func (e *EventManager) ProcessEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) (bool, error) {
|
| 62 |
-
for idx := range e.processors {
|
| 63 |
-
processor := e.processors[idx]
|
| 64 |
-
if len(vLog.Topics) > 0 && vLog.Topics[0] == processor.EventSignature() {
|
| 65 |
-
return true, e.processGenericEvent(ctx, vLog, blocks, blocksOrder, processor)
|
| 66 |
-
}
|
| 67 |
-
}
|
| 68 |
-
return false, nil
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
func (e *EventManager) processGenericEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order, processor GenericEventProcessor) error {
|
| 72 |
-
callData, err := e.callDataExtractor.ExtractCallData(ctx, vLog.BlockHash, vLog.TxHash, vLog.TxIndex)
|
| 73 |
-
if err != nil {
|
| 74 |
-
return err
|
| 75 |
-
}
|
| 76 |
-
block, err := e.addNewBlockToResult(ctx, vLog, blocks, blocksOrder)
|
| 77 |
-
if err != nil {
|
| 78 |
-
return err
|
| 79 |
-
}
|
| 80 |
-
order, err := processor.AddEventDataToBlock(ctx, vLog, block, callData)
|
| 81 |
-
if err != nil {
|
| 82 |
-
return err
|
| 83 |
-
}
|
| 84 |
-
addNewOrder(order, block.BlockHash, blocksOrder)
|
| 85 |
-
return nil
|
| 86 |
-
}
|
| 87 |
-
|
| 88 |
-
func addNewOrder(order *Order, blockHash common.Hash, blocksOrder *map[common.Hash][]Order) {
|
| 89 |
-
(*blocksOrder)[blockHash] = append((*blocksOrder)[blockHash], *order)
|
| 90 |
-
}
|
| 91 |
-
|
| 92 |
-
// addNewEvent adds a new event to the blocks array and order array.
|
| 93 |
-
// it returns the block that must be filled with event data
|
| 94 |
-
func (e *EventManager) addNewBlockToResult(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) (*Block, error) {
|
| 95 |
-
var block *Block
|
| 96 |
-
var err error
|
| 97 |
-
if !isheadBlockInArray(blocks, vLog.BlockHash, vLog.BlockNumber) {
|
| 98 |
-
// Need to add the block, doesnt mind if inside the blocks because I have to respect the order so insert at end
|
| 99 |
-
//TODO: Check if the block is already in the blocks array and copy it instead of retrieve it again
|
| 100 |
-
block, err = e.blockRetriever.RetrieveFullBlockForEvent(ctx, vLog)
|
| 101 |
-
if err != nil {
|
| 102 |
-
return nil, err
|
| 103 |
-
}
|
| 104 |
-
*blocks = append(*blocks, *block)
|
| 105 |
-
}
|
| 106 |
-
block = &(*blocks)[len(*blocks)-1]
|
| 107 |
-
return block, nil
|
| 108 |
-
}
|
| 109 |
-
|
| 110 |
-
// CallData is a struct that contains the calldata of a transaction
|
| 111 |
-
type CallData struct {
|
| 112 |
-
data []byte
|
| 113 |
-
nonce uint64
|
| 114 |
-
from common.Address
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
// NewCallData creates a new CallData struct
|
| 118 |
-
func NewCallData(data []byte, nonce uint64, from common.Address) *CallData {
|
| 119 |
-
return &CallData{
|
| 120 |
-
data: data,
|
| 121 |
-
nonce: nonce,
|
| 122 |
-
from: from,
|
| 123 |
-
}
|
| 124 |
-
}
|
| 125 |
-
|
| 126 |
-
// MethodID returns the method ID of the transaction
|
| 127 |
-
func (c *CallData) MethodID() []byte {
|
| 128 |
-
return c.data[:4]
|
| 129 |
-
}
|
| 130 |
-
|
| 131 |
-
// InputData returns the input data of the transaction
|
| 132 |
-
func (c *CallData) InputData() []byte {
|
| 133 |
-
return c.data[4:]
|
| 134 |
-
}
|
| 135 |
-
|
| 136 |
-
// Nonce returns the nonce of the transaction
|
| 137 |
-
func (c *CallData) Nonce() uint64 {
|
| 138 |
-
return c.nonce
|
| 139 |
-
}
|
| 140 |
-
|
| 141 |
-
// From returns the address of the sender of the transaction
|
| 142 |
-
func (c *CallData) From() common.Address {
|
| 143 |
-
return c.from
|
| 144 |
-
}
|
| 145 |
-
|
| 146 |
-
// CallDataExtratorGeth is a CallDataExtractor based on Geth
|
| 147 |
-
type CallDataExtratorGeth struct {
|
| 148 |
-
ethClient ethereum.ChainReader
|
| 149 |
-
}
|
| 150 |
-
|
| 151 |
-
// NewCallDataExtratorGeth creates a new CallDataExtrator based on Geth
|
| 152 |
-
func NewCallDataExtratorGeth(ethClient ethereum.ChainReader) *CallDataExtratorGeth {
|
| 153 |
-
return &CallDataExtratorGeth{
|
| 154 |
-
ethClient: ethClient,
|
| 155 |
-
}
|
| 156 |
-
}
|
| 157 |
-
|
| 158 |
-
// ExtractCallData get the call data from a transaction
|
| 159 |
-
func (e *CallDataExtratorGeth) ExtractCallData(ctx context.Context, blockHash, txHash common.Hash, txIndex uint) (*CallData, error) {
|
| 160 |
-
// Read the tx for this event.
|
| 161 |
-
tx, err := e.ethClient.TransactionInBlock(ctx, blockHash, txIndex)
|
| 162 |
-
if err != nil {
|
| 163 |
-
return nil, err
|
| 164 |
-
}
|
| 165 |
-
if tx == nil {
|
| 166 |
-
return nil, fmt.Errorf("error: tx not found in block %s at index %d", blockHash.String(), txIndex)
|
| 167 |
-
}
|
| 168 |
-
//log.Debug("tx: ", tx2string(tx))
|
| 169 |
-
if tx.Hash() != txHash {
|
| 170 |
-
return nil, fmt.Errorf("error: tx hash mismatch. want: %s have: %s", txHash, tx.Hash().String())
|
| 171 |
-
}
|
| 172 |
-
msg, err := core.TransactionToMessage(tx, types.NewLondonSigner(tx.ChainId()), big.NewInt(0))
|
| 173 |
-
if err != nil {
|
| 174 |
-
return nil, err
|
| 175 |
-
}
|
| 176 |
-
return &CallData{
|
| 177 |
-
data: tx.Data(),
|
| 178 |
-
nonce: msg.Nonce,
|
| 179 |
-
from: msg.From,
|
| 180 |
-
}, nil
|
| 181 |
-
}
|
| 182 |
-
|
| 183 |
-
// Function used to convert a transaction to a string to used as input data for unittest
|
| 184 |
-
func tx2string(tx *types.Transaction) string { //nolint:unused
|
| 185 |
-
writer := new(bytes.Buffer)
|
| 186 |
-
err := tx.EncodeRLP(writer)
|
| 187 |
-
if err != nil {
|
| 188 |
-
return "error:" + err.Error()
|
| 189 |
-
}
|
| 190 |
-
return common.Bytes2Hex(writer.Bytes())
|
| 191 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,180 +0,0 @@
|
|
| 1 |
-
package etherman_test
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"bytes"
|
| 5 |
-
"context"
|
| 6 |
-
"fmt"
|
| 7 |
-
"math/big"
|
| 8 |
-
"testing"
|
| 9 |
-
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/mockseth"
|
| 12 |
-
"github.com/ethereum/go-ethereum/common"
|
| 13 |
-
"github.com/ethereum/go-ethereum/core/types"
|
| 14 |
-
"github.com/ethereum/go-ethereum/rlp"
|
| 15 |
-
"github.com/stretchr/testify/mock"
|
| 16 |
-
"github.com/stretchr/testify/require"
|
| 17 |
-
)
|
| 18 |
-
|
| 19 |
-
type EventManagerTestData struct {
|
| 20 |
-
mockBlockRetiever *mockseth.BlockRetriever
|
| 21 |
-
|
| 22 |
-
mockProcessor *mockseth.GenericEventProcessor
|
| 23 |
-
mockCallDataExtractor *mockseth.CallDataExtractor
|
| 24 |
-
sut *etherman.EventManager
|
| 25 |
-
ctx context.Context
|
| 26 |
-
}
|
| 27 |
-
|
| 28 |
-
func NewEventManagerTestData(t *testing.T) *EventManagerTestData {
|
| 29 |
-
mockBlockRetriever := mockseth.NewBlockRetriever(t)
|
| 30 |
-
mockCallDataExtractor := mockseth.NewCallDataExtractor(t)
|
| 31 |
-
return &EventManagerTestData{
|
| 32 |
-
mockBlockRetiever: mockBlockRetriever,
|
| 33 |
-
mockCallDataExtractor: mockCallDataExtractor,
|
| 34 |
-
mockProcessor: mockseth.NewGenericEventProcessor(t),
|
| 35 |
-
sut: etherman.NewEventManager(mockBlockRetriever, mockCallDataExtractor),
|
| 36 |
-
ctx: context.TODO(),
|
| 37 |
-
}
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
func TestEventManagerNoEventToProcess(t *testing.T) {
|
| 41 |
-
data := NewEventManagerTestData(t)
|
| 42 |
-
vLog := types.Log{}
|
| 43 |
-
|
| 44 |
-
processed, err := data.sut.ProcessEvent(context.TODO(), vLog, nil, nil)
|
| 45 |
-
require.False(t, processed)
|
| 46 |
-
require.NoError(t, err)
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
func TestEventManagerEventToProcessHappyPathIntegratedWithSequenceBlobs(t *testing.T) {
|
| 50 |
-
data := NewEventManagerTestData(t)
|
| 51 |
-
mockChainReader := etherman.NewChainReaderMock(t)
|
| 52 |
-
data.sut = etherman.NewEventManager(data.mockBlockRetiever, etherman.NewCallDataExtratorGeth(mockChainReader))
|
| 53 |
-
contracts, err := etherman.NewFeijoaContracts(nil, etherman.L1Config{})
|
| 54 |
-
require.NoError(t, err)
|
| 55 |
-
processor := etherman.NewEventFeijoaSequenceBlobsProcessor(contracts)
|
| 56 |
-
data.sut.AddProcessor(processor)
|
| 57 |
-
block := etherman.Block{
|
| 58 |
-
BlockHash: common.HexToHash("0x1"),
|
| 59 |
-
BlockNumber: 1234,
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
tx := txExample()
|
| 63 |
-
vLog := types.Log{
|
| 64 |
-
Topics: []common.Hash{processor.EventSignature(),
|
| 65 |
-
common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000074")},
|
| 66 |
-
BlockNumber: block.BlockNumber,
|
| 67 |
-
BlockHash: block.BlockHash,
|
| 68 |
-
TxHash: tx.Hash(),
|
| 69 |
-
}
|
| 70 |
-
blocks := []etherman.Block{}
|
| 71 |
-
|
| 72 |
-
data.mockBlockRetiever.EXPECT().RetrieveFullBlockForEvent(data.ctx, vLog).Return(&block, nil).Once()
|
| 73 |
-
mockChainReader.EXPECT().TransactionInBlock(data.ctx, block.BlockHash, uint(0)).Return(tx, nil).Once()
|
| 74 |
-
blocksOrder := map[common.Hash][]etherman.Order{}
|
| 75 |
-
|
| 76 |
-
processed, err := data.sut.ProcessEvent(data.ctx, vLog, &blocks, &blocksOrder)
|
| 77 |
-
|
| 78 |
-
require.True(t, processed)
|
| 79 |
-
require.NoError(t, err)
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
func TestEventManagerEventToProcessHappyPath(t *testing.T) {
|
| 83 |
-
data := NewEventManagerTestData(t)
|
| 84 |
-
block := etherman.Block{
|
| 85 |
-
BlockHash: common.HexToHash("0x1"),
|
| 86 |
-
BlockNumber: 1234,
|
| 87 |
-
}
|
| 88 |
-
eventSignature := common.HexToHash("0x2")
|
| 89 |
-
tx := txExample()
|
| 90 |
-
vLog := types.Log{
|
| 91 |
-
Topics: []common.Hash{eventSignature},
|
| 92 |
-
BlockNumber: block.BlockNumber,
|
| 93 |
-
BlockHash: block.BlockHash,
|
| 94 |
-
TxHash: tx.Hash(),
|
| 95 |
-
}
|
| 96 |
-
blocks := []etherman.Block{}
|
| 97 |
-
data.mockProcessor.EXPECT().EventSignature().Return(eventSignature).Once()
|
| 98 |
-
|
| 99 |
-
data.mockBlockRetiever.EXPECT().RetrieveFullBlockForEvent(data.ctx, vLog).Return(&block, nil).Once()
|
| 100 |
-
data.mockCallDataExtractor.EXPECT().ExtractCallData(data.ctx, block.BlockHash, tx.Hash(), uint(0)).Return(ðerman.CallData{}, nil)
|
| 101 |
-
data.mockProcessor.EXPECT().AddEventDataToBlock(data.ctx, vLog, &block, mock.Anything).Return(ðerman.Order{}, nil).Once()
|
| 102 |
-
data.sut.AddProcessor(data.mockProcessor)
|
| 103 |
-
|
| 104 |
-
blocksOrder := map[common.Hash][]etherman.Order{}
|
| 105 |
-
|
| 106 |
-
processed, err := data.sut.ProcessEvent(data.ctx, vLog, &blocks, &blocksOrder)
|
| 107 |
-
|
| 108 |
-
require.True(t, processed)
|
| 109 |
-
require.NoError(t, err)
|
| 110 |
-
}
|
| 111 |
-
|
| 112 |
-
func TestCallDataExtractorExtarctCallDataHappyPath(t *testing.T) {
|
| 113 |
-
mockChainRetriever := etherman.NewChainReaderMock(t)
|
| 114 |
-
blockHash := common.HexToHash("0x1")
|
| 115 |
-
indexTx := uint(12)
|
| 116 |
-
tx := txExample()
|
| 117 |
-
mockChainRetriever.EXPECT().TransactionInBlock(context.TODO(), blockHash, indexTx).Return(tx, nil).Once()
|
| 118 |
-
callDataExtractor := etherman.NewCallDataExtratorGeth(mockChainRetriever)
|
| 119 |
-
_, err := callDataExtractor.ExtractCallData(context.TODO(), blockHash, tx.Hash(), indexTx)
|
| 120 |
-
require.NoError(t, err)
|
| 121 |
-
}
|
| 122 |
-
|
| 123 |
-
func TestCallDataExtractorExtarctCallDataTransactionInBlockReturnsErr(t *testing.T) {
|
| 124 |
-
mockChainRetriever := etherman.NewChainReaderMock(t)
|
| 125 |
-
blockHash := common.HexToHash("0x1")
|
| 126 |
-
indexTx := uint(12)
|
| 127 |
-
errReturned := fmt.Errorf("mock error")
|
| 128 |
-
mockChainRetriever.EXPECT().TransactionInBlock(context.TODO(), blockHash, indexTx).Return(nil, errReturned).Once()
|
| 129 |
-
callDataExtractor := etherman.NewCallDataExtratorGeth(mockChainRetriever)
|
| 130 |
-
_, err := callDataExtractor.ExtractCallData(context.TODO(), blockHash, common.Hash{}, indexTx)
|
| 131 |
-
require.ErrorIs(t, err, errReturned)
|
| 132 |
-
}
|
| 133 |
-
|
| 134 |
-
func TestCallDataExtractorExtarctCallDataTransactionInBlockReturnsNilTx(t *testing.T) {
|
| 135 |
-
mockChainRetriever := etherman.NewChainReaderMock(t)
|
| 136 |
-
blockHash := common.HexToHash("0x1")
|
| 137 |
-
indexTx := uint(12)
|
| 138 |
-
|
| 139 |
-
mockChainRetriever.EXPECT().TransactionInBlock(context.TODO(), blockHash, indexTx).Return(nil, nil).Once()
|
| 140 |
-
callDataExtractor := etherman.NewCallDataExtratorGeth(mockChainRetriever)
|
| 141 |
-
_, err := callDataExtractor.ExtractCallData(context.TODO(), blockHash, common.Hash{}, indexTx)
|
| 142 |
-
require.Error(t, err)
|
| 143 |
-
}
|
| 144 |
-
|
| 145 |
-
func TestCallDataExtractorExtarctCallDataTransactionInBlockReturnTxHashNotMatch(t *testing.T) {
|
| 146 |
-
mockChainRetriever := etherman.NewChainReaderMock(t)
|
| 147 |
-
blockHash := common.HexToHash("0x1")
|
| 148 |
-
indexTx := uint(12)
|
| 149 |
-
tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil)
|
| 150 |
-
mockChainRetriever.EXPECT().TransactionInBlock(context.TODO(), blockHash, indexTx).Return(tx, nil).Once()
|
| 151 |
-
callDataExtractor := etherman.NewCallDataExtratorGeth(mockChainRetriever)
|
| 152 |
-
_, err := callDataExtractor.ExtractCallData(context.TODO(), blockHash, common.Hash{}, indexTx)
|
| 153 |
-
require.Error(t, err)
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
func TestCallDataExtractorExtarctCallDataWrongTxData(t *testing.T) {
|
| 157 |
-
mockChainRetriever := etherman.NewChainReaderMock(t)
|
| 158 |
-
blockHash := common.HexToHash("0x1")
|
| 159 |
-
indexTx := uint(12)
|
| 160 |
-
tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil)
|
| 161 |
-
mockChainRetriever.EXPECT().TransactionInBlock(context.TODO(), blockHash, indexTx).Return(tx, nil).Once()
|
| 162 |
-
callDataExtractor := etherman.NewCallDataExtratorGeth(mockChainRetriever)
|
| 163 |
-
_, err := callDataExtractor.ExtractCallData(context.TODO(), blockHash, tx.Hash(), indexTx)
|
| 164 |
-
require.Error(t, err)
|
| 165 |
-
}
|
| 166 |
-
|
| 167 |
-
func txExample() *types.Transaction {
|
| 168 |
-
var tx types.Transaction
|
| 169 |
-
reader := bytes.NewBuffer(common.Hex2Bytes(txExampleRLP))
|
| 170 |
-
stream := rlp.NewStream(reader, 0)
|
| 171 |
-
err := tx.DecodeRLP(stream)
|
| 172 |
-
if err != nil {
|
| 173 |
-
panic(err)
|
| 174 |
-
}
|
| 175 |
-
return &tx
|
| 176 |
-
}
|
| 177 |
-
|
| 178 |
-
const (
|
| 179 |
-
txExampleRLP = "fa01cc3181c28501699d83808310360194d23c761025306cf5038d74feeb077cf66de134da80ba01cbc438793b4f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000006c50a878df81d7e49424968dfac5e1409bccb68fde08efdeb2225f233039b7f5fa2bb0dc95bcf9c884b2f388092e3db6ff3484770000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000001cac00000000000000000000000000000000000000000000000000000000065f3006b00000000000000000000000000000000000000000000000000000001836e210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001ca1a000001ca15000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007110b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000007080b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000b00000003000000000000000000008401546d72a04a4304c05e4033d414115b3ad1f652e9da459614f84e7ac2eec2ed6c07660023a013aa534e2b3544baadeb9b82b368d3587b50495086318f0d8289f77912180d18"
|
| 180 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,38 +0,0 @@
|
|
| 1 |
-
package etherman
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/feijoapolygonzkevm"
|
| 5 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 6 |
-
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 7 |
-
"github.com/ethereum/go-ethereum/common"
|
| 8 |
-
)
|
| 9 |
-
|
| 10 |
-
// FeijoaContracts represents the contracts of the Feijoa upgrade
|
| 11 |
-
type FeijoaContracts struct {
|
| 12 |
-
FeijoaZKEVMAddress common.Address
|
| 13 |
-
FeijoaZKEVM *feijoapolygonzkevm.Feijoapolygonzkevm
|
| 14 |
-
//FeijoaRollupManager *feijoapolygonrollupmanager.Feijoapolygonrollupmanager
|
| 15 |
-
//FeijoaGlobalExitRootManager *feijoapolygonzkevmglobalexitroot.Feijoapolygonzkevmglobalexitroot
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
// NewFeijoaContracts creates a new FeijoaContracts
|
| 19 |
-
func NewFeijoaContracts(ethClient bind.ContractBackend, l1Config L1Config) (*FeijoaContracts, error) {
|
| 20 |
-
FeijoaZKEVMAddress := l1Config.ZkEVMAddr
|
| 21 |
-
FeijoaZKEVM, err := feijoapolygonzkevm.NewFeijoapolygonzkevm(FeijoaZKEVMAddress, ethClient)
|
| 22 |
-
if err != nil {
|
| 23 |
-
log.Errorf("error creating FeijoaZKEVM client (addr: %s). Error: %w", FeijoaZKEVMAddress.String(), err)
|
| 24 |
-
return nil, err
|
| 25 |
-
}
|
| 26 |
-
|
| 27 |
-
return &FeijoaContracts{
|
| 28 |
-
FeijoaZKEVMAddress: FeijoaZKEVMAddress,
|
| 29 |
-
FeijoaZKEVM: FeijoaZKEVM,
|
| 30 |
-
}, nil
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
// GetAddresses returns the addresses of the contracts
|
| 34 |
-
func (f *FeijoaContracts) GetAddresses() []common.Address {
|
| 35 |
-
return []common.Address{
|
| 36 |
-
f.FeijoaZKEVMAddress,
|
| 37 |
-
}
|
| 38 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,173 +0,0 @@
|
|
| 1 |
-
package etherman
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"encoding/json"
|
| 6 |
-
"fmt"
|
| 7 |
-
"strings"
|
| 8 |
-
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/feijoapolygonzkevm"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
-
"github.com/ethereum/go-ethereum/accounts/abi"
|
| 12 |
-
"github.com/ethereum/go-ethereum/common"
|
| 13 |
-
"github.com/ethereum/go-ethereum/core/types"
|
| 14 |
-
"github.com/ethereum/go-ethereum/crypto"
|
| 15 |
-
)
|
| 16 |
-
|
| 17 |
-
const (
|
| 18 |
-
// SequenceBlobsOrder identifies a SequenceBlobs order
|
| 19 |
-
SequenceBlobsOrder EventOrder = "SequenceBlobs"
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
var (
|
| 23 |
-
// Events Feijoa Signatures
|
| 24 |
-
// Events new ZkEvm/RollupBase
|
| 25 |
-
// lastBlobSequenced is the count of blob sequenced after process this event
|
| 26 |
-
// if the first event have 1 blob -> lastBlobSequenced=1
|
| 27 |
-
eventSequenceBlobsSignatureHash = crypto.Keccak256Hash([]byte("SequenceBlobs(uint64)"))
|
| 28 |
-
)
|
| 29 |
-
|
| 30 |
-
// EventFeijoaSequenceBlobsProcessor is the processor for event SequenceBlobs(uint64)
|
| 31 |
-
type EventFeijoaSequenceBlobsProcessor struct {
|
| 32 |
-
contracts *FeijoaContracts
|
| 33 |
-
}
|
| 34 |
-
|
| 35 |
-
// NewEventFeijoaSequenceBlobsProcessor creates a new EventFeijoaSequenceBlobsProcessor
|
| 36 |
-
func NewEventFeijoaSequenceBlobsProcessor(contracts *FeijoaContracts) *EventFeijoaSequenceBlobsProcessor {
|
| 37 |
-
return &EventFeijoaSequenceBlobsProcessor{
|
| 38 |
-
contracts: contracts,
|
| 39 |
-
}
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
// EventSignature returns the event signature supported
|
| 43 |
-
func (e *EventFeijoaSequenceBlobsProcessor) EventSignature() common.Hash {
|
| 44 |
-
return eventSequenceBlobsSignatureHash
|
| 45 |
-
}
|
| 46 |
-
|
| 47 |
-
// AddEventDataToBlock adds the event data to the block and returns the Order
|
| 48 |
-
func (e *EventFeijoaSequenceBlobsProcessor) AddEventDataToBlock(ctx context.Context, vLog types.Log, block *Block, callData *CallData) (*Order, error) {
|
| 49 |
-
//err := contract.UnpackLog(&event, "SequenceBlobs", vLog.Data)
|
| 50 |
-
eventData, err := e.contracts.FeijoaZKEVM.ParseSequenceBlobs(vLog)
|
| 51 |
-
if err != nil {
|
| 52 |
-
return nil, err
|
| 53 |
-
}
|
| 54 |
-
for idx := range vLog.Topics {
|
| 55 |
-
log.Debugf("vlog.Topics[%d]: %s ", idx, vLog.Topics[idx].Hex())
|
| 56 |
-
}
|
| 57 |
-
log.Debugf("LastBlobSequenced: %d", eventData.LastBlobSequenced)
|
| 58 |
-
// decode Data
|
| 59 |
-
inputData, err := e.parseCallData(callData)
|
| 60 |
-
if err != nil {
|
| 61 |
-
return nil, err
|
| 62 |
-
}
|
| 63 |
-
inputData.EventData = &SequenceBlobsEventData{
|
| 64 |
-
LastBlobSequenced: eventData.LastBlobSequenced,
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
if inputData.thereIsAnyBlobType() {
|
| 68 |
-
// TODO:Retrieve blobs
|
| 69 |
-
return nil, fmt.Errorf("data-availability in blobs: not supported yet")
|
| 70 |
-
}
|
| 71 |
-
// Add the blobs to the block list
|
| 72 |
-
block.SequenceBlobs = append(block.SequenceBlobs, *inputData)
|
| 73 |
-
order := Order{
|
| 74 |
-
Name: SequenceBatchesOrder,
|
| 75 |
-
Pos: len(block.SequenceBlobs) - 1,
|
| 76 |
-
}
|
| 77 |
-
|
| 78 |
-
return &order, nil
|
| 79 |
-
// Extract Calldata
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
func (e *EventFeijoaSequenceBlobsProcessor) parseCallData(callData *CallData) (*SequenceBlobs, error) {
|
| 83 |
-
//smcAbi, err := abi.JSON(strings.NewReader(etrogpolygonzkevm.EtrogpolygonzkevmABI))
|
| 84 |
-
smcAbi, err := abi.JSON(strings.NewReader(feijoapolygonzkevm.FeijoapolygonzkevmABI))
|
| 85 |
-
if err != nil {
|
| 86 |
-
return nil, err
|
| 87 |
-
}
|
| 88 |
-
method, err := smcAbi.MethodById(callData.MethodID())
|
| 89 |
-
if err != nil {
|
| 90 |
-
return nil, err
|
| 91 |
-
}
|
| 92 |
-
// Unpack method inputs
|
| 93 |
-
data, err := method.Inputs.Unpack(callData.InputData())
|
| 94 |
-
if err != nil {
|
| 95 |
-
return nil, err
|
| 96 |
-
}
|
| 97 |
-
bytedata, err := json.Marshal(data[0])
|
| 98 |
-
if err != nil {
|
| 99 |
-
return nil, err
|
| 100 |
-
}
|
| 101 |
-
// Solidity: function sequenceBlobs((uint8,bytes)[] blobsRaw, address l2Coinbase, bytes32 finalAccInputHash) returns()
|
| 102 |
-
var blobsRaw []feijoapolygonzkevm.PolygonRollupBaseFeijoaBlobData
|
| 103 |
-
err = json.Unmarshal(bytedata, &blobsRaw)
|
| 104 |
-
if err != nil {
|
| 105 |
-
return nil, err
|
| 106 |
-
}
|
| 107 |
-
blobs := make([]SequenceBlob, 0)
|
| 108 |
-
|
| 109 |
-
for i := range blobsRaw {
|
| 110 |
-
//log.Debugf("BlobType: %d", blobs[i].BlobType)
|
| 111 |
-
var blobBlobTypeParams *BlobBlobTypeParams
|
| 112 |
-
var blobTypeParams *BlobCommonParams
|
| 113 |
-
var txData []byte
|
| 114 |
-
switch BlobType(blobsRaw[i].BlobType) {
|
| 115 |
-
case TypeCallData:
|
| 116 |
-
blobTypeParams, txData, err = parseBlobCallDataTypeParams(blobsRaw[i].BlobTypeParams)
|
| 117 |
-
if err != nil {
|
| 118 |
-
return nil, err
|
| 119 |
-
}
|
| 120 |
-
case TypeBlobTransaction:
|
| 121 |
-
return nil, fmt.Errorf("blobType 'BlobTransaction' not supported yet")
|
| 122 |
-
default:
|
| 123 |
-
return nil, fmt.Errorf("blobType not supported")
|
| 124 |
-
}
|
| 125 |
-
blobs = append(blobs, SequenceBlob{
|
| 126 |
-
Type: BlobType(blobsRaw[i].BlobType),
|
| 127 |
-
Params: *blobTypeParams,
|
| 128 |
-
Data: txData,
|
| 129 |
-
BlobBlobTypeParams: blobBlobTypeParams,
|
| 130 |
-
})
|
| 131 |
-
}
|
| 132 |
-
l1CoinBase := (data[1]).(common.Address)
|
| 133 |
-
finalAccInputHashRaw := (data[2]).([32]byte)
|
| 134 |
-
finalAccInputHash := common.Hash(finalAccInputHashRaw)
|
| 135 |
-
|
| 136 |
-
return &SequenceBlobs{
|
| 137 |
-
Blobs: blobs,
|
| 138 |
-
L2Coinbase: l1CoinBase,
|
| 139 |
-
FinalAccInputHash: finalAccInputHash,
|
| 140 |
-
}, nil
|
| 141 |
-
}
|
| 142 |
-
|
| 143 |
-
// returns data and the transtaction_data
|
| 144 |
-
func parseBlobCallDataTypeParams(data []byte) (*BlobCommonParams, []byte, error) {
|
| 145 |
-
// https://github.com/0xPolygonHermez/zkevm-contracts/blob/feature/feijoa/contracts/v2/lib/PolygonRollupBaseFeijoa.sol
|
| 146 |
-
// case: if (currentBlob.blobType == CALLDATA_BLOB_TYPE)
|
| 147 |
-
//
|
| 148 |
-
// maxSequenceTimestamp uint64
|
| 149 |
-
// zkGasLimit uint64
|
| 150 |
-
// l1InfoLeafIndex uint32
|
| 151 |
-
// transactions []byte
|
| 152 |
-
|
| 153 |
-
// Prepare blob params using ABI encoder
|
| 154 |
-
uint64Ty, _ := abi.NewType("uint64", "", nil)
|
| 155 |
-
uint32Ty, _ := abi.NewType("uint32", "", nil)
|
| 156 |
-
bytesTy, _ := abi.NewType("bytes", "", nil)
|
| 157 |
-
arguments := abi.Arguments{
|
| 158 |
-
{Type: uint64Ty},
|
| 159 |
-
{Type: uint64Ty},
|
| 160 |
-
{Type: uint32Ty},
|
| 161 |
-
{Type: bytesTy},
|
| 162 |
-
}
|
| 163 |
-
unpacked, err := arguments.Unpack(data)
|
| 164 |
-
if err != nil {
|
| 165 |
-
return nil, nil, err
|
| 166 |
-
}
|
| 167 |
-
result := &BlobCommonParams{}
|
| 168 |
-
result.MaxSequenceTimestamp = unpacked[0].(uint64)
|
| 169 |
-
result.ZkGasLimit = unpacked[1].(uint64)
|
| 170 |
-
result.L1InfoLeafIndex = unpacked[2].(uint32)
|
| 171 |
-
transactionData := unpacked[3].([]byte)
|
| 172 |
-
return result, transactionData, nil
|
| 173 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,76 +0,0 @@
|
|
| 1 |
-
package etherman
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"fmt"
|
| 5 |
-
"math/big"
|
| 6 |
-
|
| 7 |
-
"github.com/ethereum/go-ethereum/common"
|
| 8 |
-
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
| 9 |
-
)
|
| 10 |
-
|
| 11 |
-
// BlobType is the type of the blob type
|
| 12 |
-
type BlobType uint8
|
| 13 |
-
|
| 14 |
-
const (
|
| 15 |
-
// TypeCallData The data is stored on call data directly
|
| 16 |
-
TypeCallData BlobType = 0
|
| 17 |
-
// TypeBlobTransaction The data is stored on a blob
|
| 18 |
-
TypeBlobTransaction BlobType = 1
|
| 19 |
-
// TypeForcedBlob The data is a forced Blob
|
| 20 |
-
TypeForcedBlob BlobType = 2
|
| 21 |
-
)
|
| 22 |
-
|
| 23 |
-
// SequenceBlob is for each Blob inside a SequenceBlobs
|
| 24 |
-
type SequenceBlob struct {
|
| 25 |
-
Type BlobType
|
| 26 |
-
Params BlobCommonParams
|
| 27 |
-
Data []byte
|
| 28 |
-
// Field only valid if BlobType == BlobTransaction
|
| 29 |
-
BlobBlobTypeParams *BlobBlobTypeParams
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
func (s *SequenceBlob) String() string {
|
| 33 |
-
return fmt.Sprintf("Type: %d, Params: %v, Data: %v, BlobBlobTypeParams: %v", s.Type, s.Params, s.Data, s.BlobBlobTypeParams)
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
// BlobCommonParams is the data for a SequenceBlob
|
| 37 |
-
type BlobCommonParams struct {
|
| 38 |
-
MaxSequenceTimestamp uint64
|
| 39 |
-
ZkGasLimit uint64
|
| 40 |
-
L1InfoLeafIndex uint32
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
// BlobBlobTypeParams is the data for a SequenceBlob stored on a Blob
|
| 44 |
-
// case: if (currentBlob.blobType ==> BLOBTX_BLOB_TYPE)
|
| 45 |
-
// sames as calldata plus BlobIndex, ...
|
| 46 |
-
type BlobBlobTypeParams struct {
|
| 47 |
-
BlobIndex *big.Int
|
| 48 |
-
Z []byte
|
| 49 |
-
Y []byte
|
| 50 |
-
Commitment kzg4844.Commitment
|
| 51 |
-
Proof kzg4844.Proof
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
// SequenceBlobs is the data in the event SequenceBlobs
|
| 55 |
-
type SequenceBlobs struct {
|
| 56 |
-
Blobs []SequenceBlob
|
| 57 |
-
L2Coinbase common.Address // from Calldata
|
| 58 |
-
FinalAccInputHash common.Hash
|
| 59 |
-
EventData *SequenceBlobsEventData
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
// SequenceBlobsEventData is the data in the event SequenceBlobs
|
| 63 |
-
type SequenceBlobsEventData struct {
|
| 64 |
-
// LastBlobSequenced is the count of blob sequenced after process this event
|
| 65 |
-
// if the first event have 1 blob -> lastBlobSequenced=1
|
| 66 |
-
LastBlobSequenced uint64
|
| 67 |
-
}
|
| 68 |
-
|
| 69 |
-
func (s *SequenceBlobs) thereIsAnyBlobType() bool {
|
| 70 |
-
for blobIndex := range s.Blobs {
|
| 71 |
-
if s.Blobs[blobIndex].Type == TypeBlobTransaction {
|
| 72 |
-
return true
|
| 73 |
-
}
|
| 74 |
-
}
|
| 75 |
-
return false
|
| 76 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,17 +0,0 @@
|
|
| 1 |
-
package etherman
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"testing"
|
| 5 |
-
|
| 6 |
-
"github.com/stretchr/testify/require"
|
| 7 |
-
)
|
| 8 |
-
|
| 9 |
-
func TestXxx(t *testing.T) {
|
| 10 |
-
_, err := NewFeijoaContracts(nil, L1Config{})
|
| 11 |
-
require.NoError(t, err)
|
| 12 |
-
}
|
| 13 |
-
|
| 14 |
-
func TestFeijoaEventsSignature(t *testing.T) {
|
| 15 |
-
// Signature extracted from https://sepolia.etherscan.io/tx/0x644699c839d34a61c531d7ecf12390bf38c06a62715ca4edce978b9213ce3cd1#eventlog
|
| 16 |
-
require.Equal(t, "0x470f4ca4b003755c839b80ab00c3efbeb69d6eafec00e1a3677482933ec1fd0c", eventSequenceBlobsSignatureHash.String())
|
| 17 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package etherman
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
|
| 6 |
+
"github.com/ethereum/go-ethereum/common"
|
| 7 |
+
"github.com/jackc/pgx/v4"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
type dataAvailabilityProvider interface {
|
| 11 |
+
GetBatchL2Data(batchNum []uint64, hash []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error)
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
type stateProvider interface {
|
| 15 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 16 |
+
}
|
|
@@ -5,25 +5,26 @@
|
|
| 5 |
"fmt"
|
| 6 |
"math/big"
|
| 7 |
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/etrogpolygonzkevm"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/etrogpolygonzkevmbridge"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/etrogpolygonzkevmglobalexitroot"
|
| 12 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/mocketrogpolygonrollupmanager"
|
| 13 |
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/mockverifier"
|
| 14 |
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/pol"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/proxy"
|
| 16 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 17 |
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 18 |
"github.com/ethereum/go-ethereum/common"
|
| 19 |
-
"github.com/ethereum/go-ethereum/core
|
| 20 |
"github.com/ethereum/go-ethereum/crypto"
|
| 21 |
"github.com/ethereum/go-ethereum/ethclient/simulated"
|
| 22 |
)
|
| 23 |
|
| 24 |
// NewSimulatedEtherman creates an etherman that uses a simulated blockchain. It's important to notice that the ChainID of the auth
|
| 25 |
// must be 1337. The address that holds the auth will have an initial balance of 10 ETH
|
| 26 |
-
func NewSimulatedEtherman(cfg Config, auth *bind.TransactOpts) (*Client, *simulated.Backend, common.Address, *
|
| 27 |
if auth == nil {
|
| 28 |
// read only client
|
| 29 |
return &Client{}, nil, common.Address{}, nil, nil
|
|
@@ -31,14 +32,32 @@
|
|
| 31 |
// 10000000 ETH in wei
|
| 32 |
balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd
|
| 33 |
address := auth.From
|
| 34 |
-
genesisAlloc := map[common.Address]
|
| 35 |
address: {
|
| 36 |
Balance: balance,
|
| 37 |
},
|
| 38 |
}
|
| 39 |
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
|
|
|
|
| 40 |
client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
// Deploy contracts
|
| 43 |
const polDecimalPlaces = 18
|
| 44 |
totalSupply, _ := new(big.Int).SetString("10000000000000000000000000000", 10) //nolint:gomnd
|
|
@@ -61,18 +80,18 @@
|
|
| 61 |
const posRollupManager = 4
|
| 62 |
calculatedRollupManagerAddr := crypto.CreateAddress(auth.From, nonce+posRollupManager)
|
| 63 |
genesis := common.HexToHash("0xfd3434cd8f67e59d73488a2b8da242dd1f02849ea5dd99f0ca22c836c3d5b4a9") // Random value. Needs to be different to 0x0
|
| 64 |
-
exitManagerAddr, _, globalExitRoot, err :=
|
| 65 |
if err != nil {
|
| 66 |
log.Error("error: ", err)
|
| 67 |
return nil, nil, common.Address{}, nil, err
|
| 68 |
}
|
| 69 |
-
implementationBridgeAddr, _, _, err :=
|
| 70 |
if err != nil {
|
| 71 |
log.Error("error: ", err)
|
| 72 |
return nil, nil, common.Address{}, nil, err
|
| 73 |
}
|
| 74 |
|
| 75 |
-
implementationMockRollupManagerAddr, _, _, err :=
|
| 76 |
if err != nil {
|
| 77 |
log.Error("error: ", err)
|
| 78 |
return nil, nil, common.Address{}, nil, err
|
|
@@ -92,17 +111,17 @@
|
|
| 92 |
return nil, nil, common.Address{}, nil, fmt.Errorf("RollupManagerAddr (%s) is different from the expected contract address (%s)",
|
| 93 |
mockRollupManagerAddr.String(), calculatedRollupManagerAddr.String())
|
| 94 |
}
|
| 95 |
-
initZkevmAddr, _, _, err :=
|
| 96 |
if err != nil {
|
| 97 |
log.Error("error: ", err)
|
| 98 |
return nil, nil, common.Address{}, nil, err
|
| 99 |
}
|
| 100 |
-
mockRollupManager, err :=
|
| 101 |
if err != nil {
|
| 102 |
log.Error("error: ", err)
|
| 103 |
return nil, nil, common.Address{}, nil, err
|
| 104 |
}
|
| 105 |
-
br, err
|
| 106 |
if err != nil {
|
| 107 |
log.Error("error: ", err)
|
| 108 |
return nil, nil, common.Address{}, nil, err
|
|
@@ -157,13 +176,13 @@
|
|
| 157 |
bridgeAddr.String(), calculatedBridgeAddr.String())
|
| 158 |
}
|
| 159 |
|
| 160 |
-
rollupManager, err :=
|
| 161 |
if err != nil {
|
| 162 |
log.Error("error: ", err)
|
| 163 |
return nil, nil, common.Address{}, nil, err
|
| 164 |
}
|
| 165 |
|
| 166 |
-
trueZkevm, err :=
|
| 167 |
if err != nil {
|
| 168 |
log.Error("error: ", err)
|
| 169 |
return nil, nil, common.Address{}, nil, err
|
|
@@ -182,6 +201,11 @@
|
|
| 182 |
return nil, nil, common.Address{}, nil, err
|
| 183 |
}
|
| 184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
_, err = trueZkevm.SetForceBatchAddress(auth, common.Address{})
|
| 186 |
if err != nil {
|
| 187 |
log.Error("error: ", err)
|
|
@@ -190,15 +214,17 @@
|
|
| 190 |
client.Commit()
|
| 191 |
|
| 192 |
c := &Client{
|
| 193 |
-
EthClient:
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
Pol:
|
| 197 |
-
|
| 198 |
-
RollupID:
|
| 199 |
-
SCAddresses:
|
| 200 |
-
auth:
|
| 201 |
-
cfg:
|
|
|
|
|
|
|
| 202 |
}
|
| 203 |
err = c.AddOrReplaceAuth(*auth)
|
| 204 |
if err != nil {
|
|
|
|
| 5 |
"fmt"
|
| 6 |
"math/big"
|
| 7 |
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/mockpolygonrollupmanager"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/mockverifier"
|
| 10 |
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/pol"
|
| 11 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee"
|
| 12 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygonrollupmanager"
|
| 13 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygonzkevm"
|
| 14 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygonzkevmbridge"
|
| 15 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygonzkevmglobalexitroot"
|
| 16 |
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/proxy"
|
| 17 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 18 |
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 19 |
"github.com/ethereum/go-ethereum/common"
|
| 20 |
+
"github.com/ethereum/go-ethereum/core"
|
| 21 |
"github.com/ethereum/go-ethereum/crypto"
|
| 22 |
"github.com/ethereum/go-ethereum/ethclient/simulated"
|
| 23 |
)
|
| 24 |
|
| 25 |
// NewSimulatedEtherman creates an etherman that uses a simulated blockchain. It's important to notice that the ChainID of the auth
|
| 26 |
// must be 1337. The address that holds the auth will have an initial balance of 10 ETH
|
| 27 |
+
func NewSimulatedEtherman(cfg Config, auth *bind.TransactOpts, daBackend dataAvailabilityProvider, st stateProvider) (etherman *Client, ethBackend *simulated.Backend, polAddr common.Address, br *polygonzkevmbridge.Polygonzkevmbridge, err error) {
|
| 28 |
if auth == nil {
|
| 29 |
// read only client
|
| 30 |
return &Client{}, nil, common.Address{}, nil, nil
|
|
|
|
| 32 |
// 10000000 ETH in wei
|
| 33 |
balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd
|
| 34 |
address := auth.From
|
| 35 |
+
genesisAlloc := map[common.Address]core.GenesisAccount{
|
| 36 |
address: {
|
| 37 |
Balance: balance,
|
| 38 |
},
|
| 39 |
}
|
| 40 |
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
|
| 41 |
+
// client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 42 |
client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 43 |
|
| 44 |
+
// DAC Setup
|
| 45 |
+
daAddr, _, da, err := polygondatacommittee.DeployPolygondatacommittee(auth, client.Client())
|
| 46 |
+
if err != nil {
|
| 47 |
+
return nil, nil, common.Address{}, nil, err
|
| 48 |
+
}
|
| 49 |
+
client.Commit()
|
| 50 |
+
_, err = da.Initialize(auth)
|
| 51 |
+
if err != nil {
|
| 52 |
+
return nil, nil, common.Address{}, nil, err
|
| 53 |
+
}
|
| 54 |
+
client.Commit()
|
| 55 |
+
_, err = da.SetupCommittee(auth, big.NewInt(0), []string{}, []byte{})
|
| 56 |
+
if err != nil {
|
| 57 |
+
return nil, nil, common.Address{}, nil, err
|
| 58 |
+
}
|
| 59 |
+
client.Commit()
|
| 60 |
+
|
| 61 |
// Deploy contracts
|
| 62 |
const polDecimalPlaces = 18
|
| 63 |
totalSupply, _ := new(big.Int).SetString("10000000000000000000000000000", 10) //nolint:gomnd
|
|
|
|
| 80 |
const posRollupManager = 4
|
| 81 |
calculatedRollupManagerAddr := crypto.CreateAddress(auth.From, nonce+posRollupManager)
|
| 82 |
genesis := common.HexToHash("0xfd3434cd8f67e59d73488a2b8da242dd1f02849ea5dd99f0ca22c836c3d5b4a9") // Random value. Needs to be different to 0x0
|
| 83 |
+
exitManagerAddr, _, globalExitRoot, err := polygonzkevmglobalexitroot.DeployPolygonzkevmglobalexitroot(auth, client.Client(), calculatedRollupManagerAddr, calculatedBridgeAddr)
|
| 84 |
if err != nil {
|
| 85 |
log.Error("error: ", err)
|
| 86 |
return nil, nil, common.Address{}, nil, err
|
| 87 |
}
|
| 88 |
+
implementationBridgeAddr, _, _, err := polygonzkevmbridge.DeployPolygonzkevmbridge(auth, client.Client())
|
| 89 |
if err != nil {
|
| 90 |
log.Error("error: ", err)
|
| 91 |
return nil, nil, common.Address{}, nil, err
|
| 92 |
}
|
| 93 |
|
| 94 |
+
implementationMockRollupManagerAddr, _, _, err := mockpolygonrollupmanager.DeployMockpolygonrollupmanager(auth, client.Client(), exitManagerAddr, polAddr, calculatedBridgeAddr)
|
| 95 |
if err != nil {
|
| 96 |
log.Error("error: ", err)
|
| 97 |
return nil, nil, common.Address{}, nil, err
|
|
|
|
| 111 |
return nil, nil, common.Address{}, nil, fmt.Errorf("RollupManagerAddr (%s) is different from the expected contract address (%s)",
|
| 112 |
mockRollupManagerAddr.String(), calculatedRollupManagerAddr.String())
|
| 113 |
}
|
| 114 |
+
initZkevmAddr, _, _, err := polygonzkevm.DeployPolygonzkevm(auth, client.Client(), exitManagerAddr, polAddr, bridgeAddr, mockRollupManagerAddr)
|
| 115 |
if err != nil {
|
| 116 |
log.Error("error: ", err)
|
| 117 |
return nil, nil, common.Address{}, nil, err
|
| 118 |
}
|
| 119 |
+
mockRollupManager, err := mockpolygonrollupmanager.NewMockpolygonrollupmanager(mockRollupManagerAddr, client.Client())
|
| 120 |
if err != nil {
|
| 121 |
log.Error("error: ", err)
|
| 122 |
return nil, nil, common.Address{}, nil, err
|
| 123 |
}
|
| 124 |
+
br, err = polygonzkevmbridge.NewPolygonzkevmbridge(bridgeAddr, client.Client())
|
| 125 |
if err != nil {
|
| 126 |
log.Error("error: ", err)
|
| 127 |
return nil, nil, common.Address{}, nil, err
|
|
|
|
| 176 |
bridgeAddr.String(), calculatedBridgeAddr.String())
|
| 177 |
}
|
| 178 |
|
| 179 |
+
rollupManager, err := polygonrollupmanager.NewPolygonrollupmanager(mockRollupManagerAddr, client.Client())
|
| 180 |
if err != nil {
|
| 181 |
log.Error("error: ", err)
|
| 182 |
return nil, nil, common.Address{}, nil, err
|
| 183 |
}
|
| 184 |
|
| 185 |
+
trueZkevm, err := polygonzkevm.NewPolygonzkevm(zkevmAddr, client.Client()) //nolint
|
| 186 |
if err != nil {
|
| 187 |
log.Error("error: ", err)
|
| 188 |
return nil, nil, common.Address{}, nil, err
|
|
|
|
| 201 |
return nil, nil, common.Address{}, nil, err
|
| 202 |
}
|
| 203 |
|
| 204 |
+
_, err = trueZkevm.SetDataAvailabilityProtocol(auth, daAddr)
|
| 205 |
+
if err != nil {
|
| 206 |
+
log.Error("error: ", err)
|
| 207 |
+
return nil, nil, common.Address{}, nil, err
|
| 208 |
+
}
|
| 209 |
_, err = trueZkevm.SetForceBatchAddress(auth, common.Address{})
|
| 210 |
if err != nil {
|
| 211 |
log.Error("error: ", err)
|
|
|
|
| 214 |
client.Commit()
|
| 215 |
|
| 216 |
c := &Client{
|
| 217 |
+
EthClient: client.Client(),
|
| 218 |
+
ZkEVM: trueZkevm,
|
| 219 |
+
RollupManager: rollupManager,
|
| 220 |
+
Pol: polContract,
|
| 221 |
+
GlobalExitRootManager: globalExitRoot,
|
| 222 |
+
RollupID: rollupID,
|
| 223 |
+
SCAddresses: []common.Address{zkevmAddr, mockRollupManagerAddr, exitManagerAddr},
|
| 224 |
+
auth: map[common.Address]bind.TransactOpts{},
|
| 225 |
+
cfg: cfg,
|
| 226 |
+
da: daBackend,
|
| 227 |
+
state: st,
|
| 228 |
}
|
| 229 |
err = c.AddOrReplaceAuth(*auth)
|
| 230 |
if err != nil {
|
|
@@ -19,7 +19,6 @@
|
|
| 19 |
VerifiedBatches []VerifiedBatch
|
| 20 |
SequencedForceBatches [][]SequencedForceBatch
|
| 21 |
ForkIDs []ForkID
|
| 22 |
-
SequenceBlobs []SequenceBlobs
|
| 23 |
ReceivedAt time.Time
|
| 24 |
// GER data
|
| 25 |
GlobalExitRoots, L1InfoTree []GlobalExitRoot
|
|
@@ -50,9 +49,9 @@
|
|
| 50 |
Nonce uint64
|
| 51 |
Coinbase common.Address
|
| 52 |
// Struct used in preEtrog forks
|
| 53 |
-
*
|
| 54 |
// Struct used in Etrog
|
| 55 |
-
*
|
| 56 |
// Struct used in Elderberry
|
| 57 |
*SequencedBatchElderberryData
|
| 58 |
}
|
|
@@ -64,7 +63,7 @@
|
|
| 64 |
TxHash common.Hash
|
| 65 |
Nonce uint64
|
| 66 |
// Struct used in Etrog
|
| 67 |
-
*
|
| 68 |
}
|
| 69 |
|
| 70 |
// ForcedBatch represents a ForcedBatch
|
|
@@ -93,7 +92,7 @@
|
|
| 93 |
TxHash common.Hash
|
| 94 |
Timestamp time.Time
|
| 95 |
Nonce uint64
|
| 96 |
-
|
| 97 |
}
|
| 98 |
|
| 99 |
// ForkID is a sturct to track the ForkID event.
|
|
|
|
| 19 |
VerifiedBatches []VerifiedBatch
|
| 20 |
SequencedForceBatches [][]SequencedForceBatch
|
| 21 |
ForkIDs []ForkID
|
|
|
|
| 22 |
ReceivedAt time.Time
|
| 23 |
// GER data
|
| 24 |
GlobalExitRoots, L1InfoTree []GlobalExitRoot
|
|
|
|
| 49 |
Nonce uint64
|
| 50 |
Coinbase common.Address
|
| 51 |
// Struct used in preEtrog forks
|
| 52 |
+
*oldpolygonzkevm.PolygonZkEVMBatchData
|
| 53 |
// Struct used in Etrog
|
| 54 |
+
*polygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 55 |
// Struct used in Elderberry
|
| 56 |
*SequencedBatchElderberryData
|
| 57 |
}
|
|
|
|
| 63 |
TxHash common.Hash
|
| 64 |
Nonce uint64
|
| 65 |
// Struct used in Etrog
|
| 66 |
+
*polygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 67 |
}
|
| 68 |
|
| 69 |
// ForcedBatch represents a ForcedBatch
|
|
|
|
| 92 |
TxHash common.Hash
|
| 93 |
Timestamp time.Time
|
| 94 |
Nonce uint64
|
| 95 |
+
polygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 96 |
}
|
| 97 |
|
| 98 |
// ForkID is a sturct to track the ForkID event.
|
|
@@ -59,44 +59,15 @@
|
|
| 59 |
return c
|
| 60 |
}
|
| 61 |
|
| 62 |
-
// getTxNonce get the nonce for the given account
|
| 63 |
-
func (c *Client) getTxNonce(ctx context.Context, from common.Address) (uint64, error) {
|
| 64 |
-
// Get created transactions from the database for the given account
|
| 65 |
-
createdTxs, err := c.storage.GetBySenderAndStatus(ctx, from, []MonitoredTxStatus{MonitoredTxStatusCreated}, nil)
|
| 66 |
-
if err != nil {
|
| 67 |
-
return 0, fmt.Errorf("failed to get created monitored txs: %w", err)
|
| 68 |
-
}
|
| 69 |
-
|
| 70 |
-
var nonce uint64
|
| 71 |
-
if len(createdTxs) > 0 {
|
| 72 |
-
// if there are pending txs, we adjust the nonce accordingly
|
| 73 |
-
for _, createdTx := range createdTxs {
|
| 74 |
-
if createdTx.nonce > nonce {
|
| 75 |
-
nonce = createdTx.nonce
|
| 76 |
-
}
|
| 77 |
-
}
|
| 78 |
-
|
| 79 |
-
nonce++
|
| 80 |
-
} else {
|
| 81 |
-
// if there are no pending txs, we get the pending nonce from the etherman
|
| 82 |
-
if nonce, err = c.etherman.PendingNonce(ctx, from); err != nil {
|
| 83 |
-
return 0, fmt.Errorf("failed to get pending nonce: %w", err)
|
| 84 |
-
}
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
return nonce, nil
|
| 88 |
-
}
|
| 89 |
-
|
| 90 |
// Add a transaction to be sent and monitored
|
| 91 |
func (c *Client) Add(ctx context.Context, owner, id string, from common.Address, to *common.Address, value *big.Int, data []byte, gasOffset uint64, dbTx pgx.Tx) error {
|
| 92 |
-
// get nonce
|
| 93 |
-
nonce, err := c.
|
| 94 |
if err != nil {
|
| 95 |
-
err := fmt.Errorf("failed to get nonce: %w", err)
|
| 96 |
log.Errorf(err.Error())
|
| 97 |
return err
|
| 98 |
}
|
| 99 |
-
|
| 100 |
// get gas
|
| 101 |
gas, err := c.etherman.EstimateGas(ctx, from, to, value, data)
|
| 102 |
if err != nil {
|
|
@@ -594,7 +565,7 @@
|
|
| 594 |
// causing possible side effects and wasting resources.
|
| 595 |
func (c *Client) reviewMonitoredTxNonce(ctx context.Context, mTx *monitoredTx, mTxLogger *log.Logger) error {
|
| 596 |
mTxLogger.Debug("reviewing nonce")
|
| 597 |
-
nonce, err := c.
|
| 598 |
if err != nil {
|
| 599 |
err := fmt.Errorf("failed to load current nonce for acc %v: %w", mTx.from.String(), err)
|
| 600 |
mTxLogger.Errorf(err.Error())
|
|
|
|
| 59 |
return c
|
| 60 |
}
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
// Add a transaction to be sent and monitored
|
| 63 |
func (c *Client) Add(ctx context.Context, owner, id string, from common.Address, to *common.Address, value *big.Int, data []byte, gasOffset uint64, dbTx pgx.Tx) error {
|
| 64 |
+
// get next nonce
|
| 65 |
+
nonce, err := c.etherman.CurrentNonce(ctx, from)
|
| 66 |
if err != nil {
|
| 67 |
+
err := fmt.Errorf("failed to get current nonce: %w", err)
|
| 68 |
log.Errorf(err.Error())
|
| 69 |
return err
|
| 70 |
}
|
|
|
|
| 71 |
// get gas
|
| 72 |
gas, err := c.etherman.EstimateGas(ctx, from, to, value, data)
|
| 73 |
if err != nil {
|
|
|
|
| 565 |
// causing possible side effects and wasting resources.
|
| 566 |
func (c *Client) reviewMonitoredTxNonce(ctx context.Context, mTx *monitoredTx, mTxLogger *log.Logger) error {
|
| 567 |
mTxLogger.Debug("reviewing nonce")
|
| 568 |
+
nonce, err := c.etherman.CurrentNonce(ctx, mTx.from)
|
| 569 |
if err != nil {
|
| 570 |
err := fmt.Errorf("failed to load current nonce for acc %v: %w", mTx.from.String(), err)
|
| 571 |
mTxLogger.Errorf(err.Error())
|
|
@@ -47,7 +47,7 @@
|
|
| 47 |
|
| 48 |
currentNonce := uint64(1)
|
| 49 |
etherman.
|
| 50 |
-
On("
|
| 51 |
Return(currentNonce, nil).
|
| 52 |
Once()
|
| 53 |
|
|
@@ -165,7 +165,7 @@
|
|
| 165 |
// Add
|
| 166 |
currentNonce := uint64(1)
|
| 167 |
etherman.
|
| 168 |
-
On("
|
| 169 |
Return(currentNonce, nil).
|
| 170 |
Once()
|
| 171 |
|
|
@@ -331,7 +331,7 @@
|
|
| 331 |
// Add
|
| 332 |
currentNonce := uint64(1)
|
| 333 |
etherman.
|
| 334 |
-
On("
|
| 335 |
Return(currentNonce, nil).
|
| 336 |
Once()
|
| 337 |
|
|
@@ -521,7 +521,7 @@
|
|
| 521 |
// Add
|
| 522 |
currentNonce := uint64(1)
|
| 523 |
etherman.
|
| 524 |
-
On("
|
| 525 |
Return(currentNonce, nil).
|
| 526 |
Once()
|
| 527 |
|
|
@@ -593,7 +593,7 @@
|
|
| 593 |
|
| 594 |
currentNonce = uint64(2)
|
| 595 |
etherman.
|
| 596 |
-
On("
|
| 597 |
Return(currentNonce, nil).
|
| 598 |
Once()
|
| 599 |
secondGasEstimation := uint64(2)
|
|
@@ -751,7 +751,7 @@
|
|
| 751 |
|
| 752 |
currentNonce := uint64(1)
|
| 753 |
etherman.
|
| 754 |
-
On("
|
| 755 |
Return(currentNonce, nil).
|
| 756 |
Once()
|
| 757 |
|
|
@@ -832,7 +832,7 @@
|
|
| 832 |
|
| 833 |
currentNonce := uint64(1)
|
| 834 |
etherman.
|
| 835 |
-
On("
|
| 836 |
Return(currentNonce, nil).
|
| 837 |
Once()
|
| 838 |
|
|
@@ -886,7 +886,7 @@
|
|
| 886 |
|
| 887 |
currentNonce := uint64(1)
|
| 888 |
etherman.
|
| 889 |
-
On("
|
| 890 |
Return(currentNonce, nil).
|
| 891 |
Once()
|
| 892 |
|
|
|
|
| 47 |
|
| 48 |
currentNonce := uint64(1)
|
| 49 |
etherman.
|
| 50 |
+
On("CurrentNonce", ctx, from).
|
| 51 |
Return(currentNonce, nil).
|
| 52 |
Once()
|
| 53 |
|
|
|
|
| 165 |
// Add
|
| 166 |
currentNonce := uint64(1)
|
| 167 |
etherman.
|
| 168 |
+
On("CurrentNonce", ctx, from).
|
| 169 |
Return(currentNonce, nil).
|
| 170 |
Once()
|
| 171 |
|
|
|
|
| 331 |
// Add
|
| 332 |
currentNonce := uint64(1)
|
| 333 |
etherman.
|
| 334 |
+
On("CurrentNonce", ctx, from).
|
| 335 |
Return(currentNonce, nil).
|
| 336 |
Once()
|
| 337 |
|
|
|
|
| 521 |
// Add
|
| 522 |
currentNonce := uint64(1)
|
| 523 |
etherman.
|
| 524 |
+
On("CurrentNonce", ctx, from).
|
| 525 |
Return(currentNonce, nil).
|
| 526 |
Once()
|
| 527 |
|
|
|
|
| 593 |
|
| 594 |
currentNonce = uint64(2)
|
| 595 |
etherman.
|
| 596 |
+
On("CurrentNonce", ctx, from).
|
| 597 |
Return(currentNonce, nil).
|
| 598 |
Once()
|
| 599 |
secondGasEstimation := uint64(2)
|
|
|
|
| 751 |
|
| 752 |
currentNonce := uint64(1)
|
| 753 |
etherman.
|
| 754 |
+
On("CurrentNonce", ctx, from).
|
| 755 |
Return(currentNonce, nil).
|
| 756 |
Once()
|
| 757 |
|
|
|
|
| 832 |
|
| 833 |
currentNonce := uint64(1)
|
| 834 |
etherman.
|
| 835 |
+
On("CurrentNonce", ctx, from).
|
| 836 |
Return(currentNonce, nil).
|
| 837 |
Once()
|
| 838 |
|
|
|
|
| 886 |
|
| 887 |
currentNonce := uint64(1)
|
| 888 |
etherman.
|
| 889 |
+
On("CurrentNonce", ctx, from).
|
| 890 |
Return(currentNonce, nil).
|
| 891 |
Once()
|
| 892 |
|
|
@@ -16,7 +16,6 @@
|
|
| 16 |
GetTxReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
|
| 17 |
WaitTxToBeMined(ctx context.Context, tx *types.Transaction, timeout time.Duration) (bool, error)
|
| 18 |
SendTx(ctx context.Context, tx *types.Transaction) error
|
| 19 |
-
PendingNonce(ctx context.Context, account common.Address) (uint64, error)
|
| 20 |
CurrentNonce(ctx context.Context, account common.Address) (uint64, error)
|
| 21 |
SuggestedGasPrice(ctx context.Context) (*big.Int, error)
|
| 22 |
EstimateGas(ctx context.Context, from common.Address, to *common.Address, value *big.Int, data []byte) (uint64, error)
|
|
@@ -29,7 +28,6 @@
|
|
| 29 |
Add(ctx context.Context, mTx monitoredTx, dbTx pgx.Tx) error
|
| 30 |
Get(ctx context.Context, owner, id string, dbTx pgx.Tx) (monitoredTx, error)
|
| 31 |
GetByStatus(ctx context.Context, owner *string, statuses []MonitoredTxStatus, dbTx pgx.Tx) ([]monitoredTx, error)
|
| 32 |
-
GetBySenderAndStatus(ctx context.Context, sender common.Address, statuses []MonitoredTxStatus, dbTx pgx.Tx) ([]monitoredTx, error)
|
| 33 |
GetByBlock(ctx context.Context, fromBlock, toBlock *uint64, dbTx pgx.Tx) ([]monitoredTx, error)
|
| 34 |
Update(ctx context.Context, mTx monitoredTx, dbTx pgx.Tx) error
|
| 35 |
}
|
|
|
|
| 16 |
GetTxReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
|
| 17 |
WaitTxToBeMined(ctx context.Context, tx *types.Transaction, timeout time.Duration) (bool, error)
|
| 18 |
SendTx(ctx context.Context, tx *types.Transaction) error
|
|
|
|
| 19 |
CurrentNonce(ctx context.Context, account common.Address) (uint64, error)
|
| 20 |
SuggestedGasPrice(ctx context.Context) (*big.Int, error)
|
| 21 |
EstimateGas(ctx context.Context, from common.Address, to *common.Address, value *big.Int, data []byte) (uint64, error)
|
|
|
|
| 28 |
Add(ctx context.Context, mTx monitoredTx, dbTx pgx.Tx) error
|
| 29 |
Get(ctx context.Context, owner, id string, dbTx pgx.Tx) (monitoredTx, error)
|
| 30 |
GetByStatus(ctx context.Context, owner *string, statuses []MonitoredTxStatus, dbTx pgx.Tx) ([]monitoredTx, error)
|
|
|
|
| 31 |
GetByBlock(ctx context.Context, fromBlock, toBlock *uint64, dbTx pgx.Tx) ([]monitoredTx, error)
|
| 32 |
Update(ctx context.Context, mTx monitoredTx, dbTx pgx.Tx) error
|
| 33 |
}
|
|
@@ -123,50 +123,6 @@
|
|
| 123 |
return mTxs, nil
|
| 124 |
}
|
| 125 |
|
| 126 |
-
// GetBySenderAndStatus loads all monitored txs of the given sender that match the provided status
|
| 127 |
-
func (s *PostgresStorage) GetBySenderAndStatus(ctx context.Context, sender common.Address, statuses []MonitoredTxStatus, dbTx pgx.Tx) ([]monitoredTx, error) {
|
| 128 |
-
hasStatusToFilter := len(statuses) > 0
|
| 129 |
-
|
| 130 |
-
conn := s.dbConn(dbTx)
|
| 131 |
-
cmd := `
|
| 132 |
-
SELECT owner, id, from_addr, to_addr, nonce, value, data, gas, gas_offset, gas_price, status, block_num, history, created_at, updated_at
|
| 133 |
-
FROM state.monitored_txs
|
| 134 |
-
WHERE from_addr = $1`
|
| 135 |
-
if hasStatusToFilter {
|
| 136 |
-
cmd += `
|
| 137 |
-
AND status = ANY($2)`
|
| 138 |
-
}
|
| 139 |
-
cmd += `
|
| 140 |
-
ORDER BY created_at`
|
| 141 |
-
|
| 142 |
-
mTxs := []monitoredTx{}
|
| 143 |
-
|
| 144 |
-
var rows pgx.Rows
|
| 145 |
-
var err error
|
| 146 |
-
if hasStatusToFilter {
|
| 147 |
-
rows, err = conn.Query(ctx, cmd, sender.String(), statuses)
|
| 148 |
-
} else {
|
| 149 |
-
rows, err = conn.Query(ctx, cmd, sender.String())
|
| 150 |
-
}
|
| 151 |
-
|
| 152 |
-
if errors.Is(err, pgx.ErrNoRows) {
|
| 153 |
-
return []monitoredTx{}, nil
|
| 154 |
-
} else if err != nil {
|
| 155 |
-
return nil, err
|
| 156 |
-
}
|
| 157 |
-
|
| 158 |
-
for rows.Next() {
|
| 159 |
-
mTx := monitoredTx{}
|
| 160 |
-
err := s.scanMtx(rows, &mTx)
|
| 161 |
-
if err != nil {
|
| 162 |
-
return nil, err
|
| 163 |
-
}
|
| 164 |
-
mTxs = append(mTxs, mTx)
|
| 165 |
-
}
|
| 166 |
-
|
| 167 |
-
return mTxs, nil
|
| 168 |
-
}
|
| 169 |
-
|
| 170 |
// GetByBlock loads all monitored tx that have the blockNumber between
|
| 171 |
// fromBlock and toBlock
|
| 172 |
func (s *PostgresStorage) GetByBlock(ctx context.Context, fromBlock, toBlock *uint64, dbTx pgx.Tx) ([]monitoredTx, error) {
|
|
|
|
| 123 |
return mTxs, nil
|
| 124 |
}
|
| 125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
// GetByBlock loads all monitored tx that have the blockNumber between
|
| 127 |
// fromBlock and toBlock
|
| 128 |
func (s *PostgresStorage) GetByBlock(ctx context.Context, fromBlock, toBlock *uint64, dbTx pgx.Tx) ([]monitoredTx, error) {
|
|
@@ -163,72 +163,6 @@
|
|
| 163 |
assert.Equal(t, "confirmed2", mTxs[7].id)
|
| 164 |
}
|
| 165 |
|
| 166 |
-
func TestAddAndGetBySenderAndStatus(t *testing.T) {
|
| 167 |
-
dbCfg := dbutils.NewStateConfigFromEnv()
|
| 168 |
-
require.NoError(t, dbutils.InitOrResetState(dbCfg))
|
| 169 |
-
|
| 170 |
-
storage, err := NewPostgresStorage(dbCfg)
|
| 171 |
-
require.NoError(t, err)
|
| 172 |
-
|
| 173 |
-
from := common.HexToAddress("0x1")
|
| 174 |
-
to := common.HexToAddress("0x2")
|
| 175 |
-
baseMtx := monitoredTx{
|
| 176 |
-
owner: "owner", from: common.HexToAddress("0x1"), to: &to, nonce: uint64(1), value: big.NewInt(2), data: []byte("data"), blockNumber: big.NewInt(1),
|
| 177 |
-
gas: uint64(3), gasPrice: big.NewInt(4), history: map[common.Hash]bool{common.HexToHash("0x3"): true, common.HexToHash("0x4"): true},
|
| 178 |
-
}
|
| 179 |
-
|
| 180 |
-
type mTxReplaceInfo struct {
|
| 181 |
-
id string
|
| 182 |
-
status MonitoredTxStatus
|
| 183 |
-
}
|
| 184 |
-
|
| 185 |
-
mTxsReplaceInfo := []mTxReplaceInfo{
|
| 186 |
-
{id: "created1", status: MonitoredTxStatusCreated},
|
| 187 |
-
{id: "sent1", status: MonitoredTxStatusSent},
|
| 188 |
-
{id: "failed1", status: MonitoredTxStatusFailed},
|
| 189 |
-
{id: "confirmed1", status: MonitoredTxStatusConfirmed},
|
| 190 |
-
{id: "created2", status: MonitoredTxStatusCreated},
|
| 191 |
-
{id: "sent2", status: MonitoredTxStatusSent},
|
| 192 |
-
{id: "failed2", status: MonitoredTxStatusFailed},
|
| 193 |
-
{id: "confirmed2", status: MonitoredTxStatusConfirmed},
|
| 194 |
-
}
|
| 195 |
-
|
| 196 |
-
for _, replaceInfo := range mTxsReplaceInfo {
|
| 197 |
-
baseMtx.id = replaceInfo.id
|
| 198 |
-
baseMtx.status = replaceInfo.status
|
| 199 |
-
baseMtx.createdAt = baseMtx.createdAt.Add(time.Microsecond)
|
| 200 |
-
baseMtx.updatedAt = baseMtx.updatedAt.Add(time.Microsecond)
|
| 201 |
-
err = storage.Add(context.Background(), baseMtx, nil)
|
| 202 |
-
require.NoError(t, err)
|
| 203 |
-
}
|
| 204 |
-
|
| 205 |
-
mTxs, err := storage.GetBySenderAndStatus(context.Background(), from, []MonitoredTxStatus{MonitoredTxStatusConfirmed}, nil)
|
| 206 |
-
require.NoError(t, err)
|
| 207 |
-
assert.Equal(t, 2, len(mTxs))
|
| 208 |
-
assert.Equal(t, "confirmed1", mTxs[0].id)
|
| 209 |
-
assert.Equal(t, "confirmed2", mTxs[1].id)
|
| 210 |
-
|
| 211 |
-
mTxs, err = storage.GetBySenderAndStatus(context.Background(), from, []MonitoredTxStatus{MonitoredTxStatusSent, MonitoredTxStatusCreated}, nil)
|
| 212 |
-
require.NoError(t, err)
|
| 213 |
-
assert.Equal(t, 4, len(mTxs))
|
| 214 |
-
assert.Equal(t, "created1", mTxs[0].id)
|
| 215 |
-
assert.Equal(t, "sent1", mTxs[1].id)
|
| 216 |
-
assert.Equal(t, "created2", mTxs[2].id)
|
| 217 |
-
assert.Equal(t, "sent2", mTxs[3].id)
|
| 218 |
-
|
| 219 |
-
mTxs, err = storage.GetBySenderAndStatus(context.Background(), from, []MonitoredTxStatus{}, nil)
|
| 220 |
-
require.NoError(t, err)
|
| 221 |
-
assert.Equal(t, 8, len(mTxs))
|
| 222 |
-
assert.Equal(t, "created1", mTxs[0].id)
|
| 223 |
-
assert.Equal(t, "sent1", mTxs[1].id)
|
| 224 |
-
assert.Equal(t, "failed1", mTxs[2].id)
|
| 225 |
-
assert.Equal(t, "confirmed1", mTxs[3].id)
|
| 226 |
-
assert.Equal(t, "created2", mTxs[4].id)
|
| 227 |
-
assert.Equal(t, "sent2", mTxs[5].id)
|
| 228 |
-
assert.Equal(t, "failed2", mTxs[6].id)
|
| 229 |
-
assert.Equal(t, "confirmed2", mTxs[7].id)
|
| 230 |
-
}
|
| 231 |
-
|
| 232 |
func TestAddRepeated(t *testing.T) {
|
| 233 |
dbCfg := dbutils.NewStateConfigFromEnv()
|
| 234 |
require.NoError(t, dbutils.InitOrResetState(dbCfg))
|
|
|
|
| 163 |
assert.Equal(t, "confirmed2", mTxs[7].id)
|
| 164 |
}
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
func TestAddRepeated(t *testing.T) {
|
| 167 |
dbCfg := dbutils.NewStateConfigFromEnv()
|
| 168 |
require.NoError(t, dbutils.InitOrResetState(dbCfg))
|
|
@@ -42,6 +42,9 @@
|
|
| 42 |
EventID_SynchronizerHalt EventID = "SYNCHRONIZER HALT"
|
| 43 |
// EventID_SequenceSenderHalt is triggered when the SequenceSender halts
|
| 44 |
EventID_SequenceSenderHalt EventID = "SEQUENCESENDER HALT"
|
|
|
|
|
|
|
|
|
|
| 45 |
// EventID_NodeOOC is triggered when an OOC at node level is detected
|
| 46 |
EventID_NodeOOC EventID = "NODE OOC"
|
| 47 |
// EventID_UsedZKCountersOverflow is triggered when used ZK counters exceeds remaining batch ZK counters
|
|
|
|
| 42 |
EventID_SynchronizerHalt EventID = "SYNCHRONIZER HALT"
|
| 43 |
// EventID_SequenceSenderHalt is triggered when the SequenceSender halts
|
| 44 |
EventID_SequenceSenderHalt EventID = "SEQUENCESENDER HALT"
|
| 45 |
+
// EventID_UnsupportedPrecompile is triggered when the executor returns an unsupported precompile error
|
| 46 |
+
EventID_UnsupportedPrecompile EventID = "UNSUPPORTED PRECOMPILE"
|
| 47 |
+
|
| 48 |
// EventID_NodeOOC is triggered when an OOC at node level is detected
|
| 49 |
EventID_NodeOOC EventID = "NODE OOC"
|
| 50 |
// EventID_UsedZKCountersOverflow is triggered when used ZK counters exceeds remaining batch ZK counters
|
|
@@ -29,7 +29,7 @@
|
|
| 29 |
}
|
| 30 |
|
| 31 |
// LogExecutorError is used to store Executor error for runtime debugging
|
| 32 |
-
func (e *EventLog) LogExecutorError(ctx context.Context, responseError executor.ExecutorError, processBatchRequest
|
| 33 |
timestamp := time.Now()
|
| 34 |
|
| 35 |
// if it's a user related error, ignore it
|
|
@@ -47,6 +47,30 @@
|
|
| 47 |
log.Errorf("error found in the executor: %v at %v", responseError, timestamp)
|
| 48 |
payload, err := json.Marshal(processBatchRequest)
|
| 49 |
if err != nil {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
log.Errorf("error marshaling payload: %v", err)
|
| 51 |
} else {
|
| 52 |
event := &Event{
|
|
|
|
| 29 |
}
|
| 30 |
|
| 31 |
// LogExecutorError is used to store Executor error for runtime debugging
|
| 32 |
+
func (e *EventLog) LogExecutorError(ctx context.Context, responseError executor.ExecutorError, processBatchRequest *executor.ProcessBatchRequest) {
|
| 33 |
timestamp := time.Now()
|
| 34 |
|
| 35 |
// if it's a user related error, ignore it
|
|
|
|
| 47 |
log.Errorf("error found in the executor: %v at %v", responseError, timestamp)
|
| 48 |
payload, err := json.Marshal(processBatchRequest)
|
| 49 |
if err != nil {
|
| 50 |
+
log.Errorf("error marshaling payload: %v", err)
|
| 51 |
+
} else {
|
| 52 |
+
event := &Event{
|
| 53 |
+
ReceivedAt: timestamp,
|
| 54 |
+
Source: Source_Node,
|
| 55 |
+
Component: Component_Executor,
|
| 56 |
+
Level: Level_Error,
|
| 57 |
+
EventID: EventID_ExecutorError,
|
| 58 |
+
Description: responseError.String(),
|
| 59 |
+
Json: string(payload),
|
| 60 |
+
}
|
| 61 |
+
err = e.storage.LogEvent(ctx, event)
|
| 62 |
+
if err != nil {
|
| 63 |
+
log.Errorf("error storing event: %v", err)
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// LogExecutorErrorV2 is used to store Executor error for runtime debugging
|
| 69 |
+
func (e *EventLog) LogExecutorErrorV2(ctx context.Context, responseError executor.ExecutorError, processBatchRequest *executor.ProcessBatchRequestV2) {
|
| 70 |
+
timestamp := time.Now()
|
| 71 |
+
log.Errorf("error found in the executor: %v at %v", responseError, timestamp)
|
| 72 |
+
payload, err := json.Marshal(processBatchRequest)
|
| 73 |
+
if err != nil {
|
| 74 |
log.Errorf("error marshaling payload: %v", err)
|
| 75 |
} else {
|
| 76 |
event := &Event{
|
|
@@ -30,3 +30,6 @@
|
|
| 30 |
include:
|
| 31 |
- EXC0012 # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
| 32 |
- EXC0014 # EXC0014 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
include:
|
| 31 |
- EXC0012 # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
| 32 |
- EXC0014 # EXC0014 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
| 33 |
+
exclude-rules:
|
| 34 |
+
- path: cmd/policy.go
|
| 35 |
+
text: "unused"
|
|
@@ -3,35 +3,35 @@
|
|
| 3 |
go 1.21
|
| 4 |
|
| 5 |
require (
|
| 6 |
-
github.com/0xPolygonHermez/zkevm-data-streamer v0.2.
|
| 7 |
github.com/didip/tollbooth/v6 v6.1.2
|
| 8 |
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127
|
| 9 |
-
github.com/ethereum/go-ethereum v1.13.
|
| 10 |
github.com/go-git/go-billy/v5 v5.5.0
|
| 11 |
-
github.com/go-git/go-git/v5 v5.
|
| 12 |
github.com/gobuffalo/packr/v2 v2.8.3
|
| 13 |
-
github.com/google/uuid v1.
|
| 14 |
github.com/habx/pg-commands v0.6.1
|
| 15 |
github.com/hermeznetwork/tracerr v0.3.2
|
| 16 |
-
github.com/iden3/go-iden3-crypto v0.0.
|
| 17 |
github.com/invopop/jsonschema v0.12.0
|
| 18 |
-
github.com/jackc/pgconn v1.14.
|
| 19 |
-
github.com/jackc/pgx/v4 v4.18.
|
| 20 |
github.com/mitchellh/mapstructure v1.5.0
|
| 21 |
-
github.com/prometheus/client_model v0.
|
| 22 |
-
github.com/prometheus/common v0.
|
| 23 |
github.com/rubenv/sql-migrate v1.6.1
|
| 24 |
github.com/spf13/afero v1.11.0
|
| 25 |
-
github.com/spf13/viper v1.
|
| 26 |
-
github.com/stretchr/testify v1.
|
| 27 |
-
github.com/umbracle/ethgo v0.1.
|
| 28 |
-
github.com/urfave/cli/v2 v2.
|
| 29 |
-
go.uber.org/zap v1.
|
| 30 |
-
golang.org/x/crypto v0.
|
| 31 |
-
golang.org/x/net v0.
|
| 32 |
-
golang.org/x/sync v0.
|
| 33 |
-
google.golang.org/grpc v1.
|
| 34 |
-
google.golang.org/protobuf v1.
|
| 35 |
gopkg.in/yaml.v2 v2.4.0
|
| 36 |
gopkg.in/yaml.v3 v3.0.1
|
| 37 |
)
|
|
@@ -40,16 +40,16 @@
|
|
| 40 |
dario.cat/mergo v1.0.0 // indirect
|
| 41 |
github.com/DataDog/zstd v1.5.2 // indirect
|
| 42 |
github.com/Microsoft/go-winio v0.6.1 // indirect
|
| 43 |
-
github.com/ProtonMail/go-crypto
|
| 44 |
github.com/StackExchange/wmi v1.2.1 // indirect
|
| 45 |
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
|
| 46 |
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
| 47 |
github.com/beorn7/perks v1.0.1 // indirect
|
| 48 |
-
github.com/bits-and-blooms/bitset v1.
|
| 49 |
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
| 50 |
github.com/buger/jsonparser v1.1.1 // indirect
|
| 51 |
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
| 52 |
-
github.com/cloudflare/circl v1.3.
|
| 53 |
github.com/cockroachdb/errors v1.9.1 // indirect
|
| 54 |
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
| 55 |
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect
|
|
@@ -57,18 +57,18 @@
|
|
| 57 |
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
| 58 |
github.com/consensys/bavard v0.1.13 // indirect
|
| 59 |
github.com/consensys/gnark-crypto v0.12.1 // indirect
|
| 60 |
-
github.com/cpuguy83/go-md2man/v2 v2.0.
|
| 61 |
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect
|
| 62 |
github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect
|
| 63 |
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
| 64 |
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
| 65 |
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
|
| 66 |
-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.
|
| 67 |
github.com/dlclark/regexp2 v1.7.0 // indirect
|
| 68 |
github.com/emirpasic/gods v1.18.1 // indirect
|
| 69 |
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
|
| 70 |
-
github.com/fjl/memsize v0.0.
|
| 71 |
-
github.com/fsnotify/fsnotify v1.
|
| 72 |
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
| 73 |
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
|
| 74 |
github.com/getsentry/sentry-go v0.18.0 // indirect
|
|
@@ -83,23 +83,25 @@
|
|
| 83 |
github.com/gogo/protobuf v1.3.2 // indirect
|
| 84 |
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
| 85 |
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
|
|
|
| 86 |
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
| 87 |
github.com/google/gofuzz v1.2.0 // indirect
|
| 88 |
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
|
| 89 |
github.com/hashicorp/go-bexpr v0.1.10 // indirect
|
| 90 |
github.com/hashicorp/hcl v1.0.0 // indirect
|
| 91 |
-
github.com/holiman/billy v0.0.0-
|
| 92 |
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
|
| 93 |
github.com/huin/goupnp v1.3.0 // indirect
|
| 94 |
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
| 95 |
github.com/jackc/pgio v1.0.0 // indirect
|
| 96 |
github.com/jackc/pgpassfile v1.0.0 // indirect
|
| 97 |
-
github.com/jackc/pgproto3/v2 v2.3.
|
| 98 |
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
| 99 |
github.com/jackc/pgtype v1.14.0 // indirect
|
| 100 |
github.com/jackc/puddle v1.3.0 // indirect
|
| 101 |
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
| 102 |
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
|
|
|
| 103 |
github.com/karrick/godirwalk v1.17.0 // indirect
|
| 104 |
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
| 105 |
github.com/klauspost/compress v1.17.0 // indirect
|
|
@@ -114,6 +116,8 @@
|
|
| 114 |
github.com/mattn/go-colorable v0.1.13 // indirect
|
| 115 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
| 116 |
github.com/mattn/go-runewidth v0.0.13 // indirect
|
|
|
|
|
|
|
| 117 |
github.com/mitchellh/pointerstructure v1.2.0 // indirect
|
| 118 |
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
| 119 |
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
|
@@ -126,17 +130,17 @@
|
|
| 126 |
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
| 127 |
github.com/rs/cors v1.7.0 // indirect
|
| 128 |
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
| 129 |
-
github.com/sagikazarmark/locafero v0.
|
| 130 |
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
| 131 |
-
github.com/sergi/go-diff v1.
|
| 132 |
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
|
| 133 |
github.com/sirupsen/logrus v1.9.0 // indirect
|
| 134 |
-
github.com/skeema/knownhosts v1.2.
|
| 135 |
github.com/sourcegraph/conc v0.3.0 // indirect
|
| 136 |
-
github.com/spf13/cast v1.
|
| 137 |
github.com/spf13/pflag v1.0.5 // indirect
|
| 138 |
github.com/status-im/keycard-go v0.2.0 // indirect
|
| 139 |
-
github.com/stretchr/objx v0.5.
|
| 140 |
github.com/subosito/gotenv v1.6.0 // indirect
|
| 141 |
github.com/supranational/blst v0.3.11 // indirect
|
| 142 |
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
|
@@ -146,15 +150,15 @@
|
|
| 146 |
github.com/valyala/fastjson v1.4.1 // indirect
|
| 147 |
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
| 148 |
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
| 149 |
-
github.com/xrash/smetrics v0.0.0-
|
| 150 |
go.uber.org/multierr v1.10.0 // indirect
|
| 151 |
golang.org/x/mod v0.14.0 // indirect
|
| 152 |
-
golang.org/x/sys v0.
|
| 153 |
-
golang.org/x/term v0.
|
| 154 |
golang.org/x/text v0.14.0 // indirect
|
| 155 |
golang.org/x/time v0.5.0 // indirect
|
| 156 |
golang.org/x/tools v0.15.0 // indirect
|
| 157 |
-
google.golang.org/genproto/googleapis/rpc v0.0.0-
|
| 158 |
gopkg.in/ini.v1 v1.67.0 // indirect
|
| 159 |
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
| 160 |
gopkg.in/warnings.v0 v0.1.2 // indirect
|
|
@@ -168,7 +172,9 @@
|
|
| 168 |
)
|
| 169 |
|
| 170 |
require (
|
|
|
|
|
|
|
| 171 |
github.com/fatih/color v1.16.0
|
| 172 |
-
github.com/prometheus/client_golang v1.
|
| 173 |
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
| 174 |
)
|
|
|
|
| 3 |
go 1.21
|
| 4 |
|
| 5 |
require (
|
| 6 |
+
github.com/0xPolygonHermez/zkevm-data-streamer v0.2.3-0.20240422135400-0df0d27226b3
|
| 7 |
github.com/didip/tollbooth/v6 v6.1.2
|
| 8 |
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127
|
| 9 |
+
github.com/ethereum/go-ethereum v1.13.11
|
| 10 |
github.com/go-git/go-billy/v5 v5.5.0
|
| 11 |
+
github.com/go-git/go-git/v5 v5.11.0
|
| 12 |
github.com/gobuffalo/packr/v2 v2.8.3
|
| 13 |
+
github.com/google/uuid v1.5.0
|
| 14 |
github.com/habx/pg-commands v0.6.1
|
| 15 |
github.com/hermeznetwork/tracerr v0.3.2
|
| 16 |
+
github.com/iden3/go-iden3-crypto v0.0.15
|
| 17 |
github.com/invopop/jsonschema v0.12.0
|
| 18 |
+
github.com/jackc/pgconn v1.14.1
|
| 19 |
+
github.com/jackc/pgx/v4 v4.18.1
|
| 20 |
github.com/mitchellh/mapstructure v1.5.0
|
| 21 |
+
github.com/prometheus/client_model v0.5.0
|
| 22 |
+
github.com/prometheus/common v0.45.0
|
| 23 |
github.com/rubenv/sql-migrate v1.6.1
|
| 24 |
github.com/spf13/afero v1.11.0
|
| 25 |
+
github.com/spf13/viper v1.18.2
|
| 26 |
+
github.com/stretchr/testify v1.8.4
|
| 27 |
+
github.com/umbracle/ethgo v0.1.4-0.20230712173909-df37dddf16f0
|
| 28 |
+
github.com/urfave/cli/v2 v2.26.0
|
| 29 |
+
go.uber.org/zap v1.26.0
|
| 30 |
+
golang.org/x/crypto v0.18.0
|
| 31 |
+
golang.org/x/net v0.20.0
|
| 32 |
+
golang.org/x/sync v0.5.0
|
| 33 |
+
google.golang.org/grpc v1.60.1
|
| 34 |
+
google.golang.org/protobuf v1.32.0
|
| 35 |
gopkg.in/yaml.v2 v2.4.0
|
| 36 |
gopkg.in/yaml.v3 v3.0.1
|
| 37 |
)
|
|
|
|
| 40 |
dario.cat/mergo v1.0.0 // indirect
|
| 41 |
github.com/DataDog/zstd v1.5.2 // indirect
|
| 42 |
github.com/Microsoft/go-winio v0.6.1 // indirect
|
| 43 |
+
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
| 44 |
github.com/StackExchange/wmi v1.2.1 // indirect
|
| 45 |
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
|
| 46 |
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
| 47 |
github.com/beorn7/perks v1.0.1 // indirect
|
| 48 |
+
github.com/bits-and-blooms/bitset v1.12.0 // indirect
|
| 49 |
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
| 50 |
github.com/buger/jsonparser v1.1.1 // indirect
|
| 51 |
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
| 52 |
+
github.com/cloudflare/circl v1.3.3 // indirect
|
| 53 |
github.com/cockroachdb/errors v1.9.1 // indirect
|
| 54 |
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
| 55 |
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect
|
|
|
|
| 57 |
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
| 58 |
github.com/consensys/bavard v0.1.13 // indirect
|
| 59 |
github.com/consensys/gnark-crypto v0.12.1 // indirect
|
| 60 |
+
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
| 61 |
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect
|
| 62 |
github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect
|
| 63 |
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
| 64 |
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
| 65 |
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
|
| 66 |
+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
| 67 |
github.com/dlclark/regexp2 v1.7.0 // indirect
|
| 68 |
github.com/emirpasic/gods v1.18.1 // indirect
|
| 69 |
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
|
| 70 |
+
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
| 71 |
+
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
| 72 |
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
| 73 |
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
|
| 74 |
github.com/getsentry/sentry-go v0.18.0 // indirect
|
|
|
|
| 83 |
github.com/gogo/protobuf v1.3.2 // indirect
|
| 84 |
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
| 85 |
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
| 86 |
+
github.com/golang/protobuf v1.5.3 // indirect
|
| 87 |
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
| 88 |
github.com/google/gofuzz v1.2.0 // indirect
|
| 89 |
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
|
| 90 |
github.com/hashicorp/go-bexpr v0.1.10 // indirect
|
| 91 |
github.com/hashicorp/hcl v1.0.0 // indirect
|
| 92 |
+
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect
|
| 93 |
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
|
| 94 |
github.com/huin/goupnp v1.3.0 // indirect
|
| 95 |
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
| 96 |
github.com/jackc/pgio v1.0.0 // indirect
|
| 97 |
github.com/jackc/pgpassfile v1.0.0 // indirect
|
| 98 |
+
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
|
| 99 |
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
| 100 |
github.com/jackc/pgtype v1.14.0 // indirect
|
| 101 |
github.com/jackc/puddle v1.3.0 // indirect
|
| 102 |
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
| 103 |
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
| 104 |
+
github.com/jmoiron/sqlx v1.2.0 // indirect
|
| 105 |
github.com/karrick/godirwalk v1.17.0 // indirect
|
| 106 |
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
| 107 |
github.com/klauspost/compress v1.17.0 // indirect
|
|
|
|
| 116 |
github.com/mattn/go-colorable v0.1.13 // indirect
|
| 117 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
| 118 |
github.com/mattn/go-runewidth v0.0.13 // indirect
|
| 119 |
+
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
| 120 |
+
github.com/miguelmota/go-solidity-sha3 v0.1.1 // indirect
|
| 121 |
github.com/mitchellh/pointerstructure v1.2.0 // indirect
|
| 122 |
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
| 123 |
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
|
|
|
| 130 |
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
| 131 |
github.com/rs/cors v1.7.0 // indirect
|
| 132 |
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
| 133 |
+
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
| 134 |
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
| 135 |
+
github.com/sergi/go-diff v1.2.0 // indirect
|
| 136 |
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
|
| 137 |
github.com/sirupsen/logrus v1.9.0 // indirect
|
| 138 |
+
github.com/skeema/knownhosts v1.2.1 // indirect
|
| 139 |
github.com/sourcegraph/conc v0.3.0 // indirect
|
| 140 |
+
github.com/spf13/cast v1.6.0 // indirect
|
| 141 |
github.com/spf13/pflag v1.0.5 // indirect
|
| 142 |
github.com/status-im/keycard-go v0.2.0 // indirect
|
| 143 |
+
github.com/stretchr/objx v0.5.0 // indirect
|
| 144 |
github.com/subosito/gotenv v1.6.0 // indirect
|
| 145 |
github.com/supranational/blst v0.3.11 // indirect
|
| 146 |
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
|
|
|
| 150 |
github.com/valyala/fastjson v1.4.1 // indirect
|
| 151 |
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
| 152 |
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
| 153 |
+
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
| 154 |
go.uber.org/multierr v1.10.0 // indirect
|
| 155 |
golang.org/x/mod v0.14.0 // indirect
|
| 156 |
+
golang.org/x/sys v0.16.0 // indirect
|
| 157 |
+
golang.org/x/term v0.16.0 // indirect
|
| 158 |
golang.org/x/text v0.14.0 // indirect
|
| 159 |
golang.org/x/time v0.5.0 // indirect
|
| 160 |
golang.org/x/tools v0.15.0 // indirect
|
| 161 |
+
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
|
| 162 |
gopkg.in/ini.v1 v1.67.0 // indirect
|
| 163 |
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
| 164 |
gopkg.in/warnings.v0 v0.1.2 // indirect
|
|
|
|
| 172 |
)
|
| 173 |
|
| 174 |
require (
|
| 175 |
+
github.com/0xPolygon/agglayer v0.0.1
|
| 176 |
+
github.com/0xPolygon/cdk-data-availability v0.0.5
|
| 177 |
github.com/fatih/color v1.16.0
|
| 178 |
+
github.com/prometheus/client_golang v1.18.0
|
| 179 |
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
| 180 |
)
|
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# .goreleaser-cdk.yaml
|
| 2 |
+
project_name: cdk-validium-node
|
| 3 |
+
|
| 4 |
+
release:
|
| 5 |
+
disable: false
|
| 6 |
+
draft: true
|
| 7 |
+
prerelease: auto
|
| 8 |
+
|
| 9 |
+
before:
|
| 10 |
+
hooks:
|
| 11 |
+
- go mod download
|
| 12 |
+
- go install github.com/gobuffalo/packr/v2/packr2@v2.8.3
|
| 13 |
+
- packr2
|
| 14 |
+
|
| 15 |
+
builds:
|
| 16 |
+
- main: ./cmd/
|
| 17 |
+
binary: zkevm-node
|
| 18 |
+
goos:
|
| 19 |
+
- linux
|
| 20 |
+
- darwin
|
| 21 |
+
goarch:
|
| 22 |
+
- amd64
|
| 23 |
+
- arm64
|
| 24 |
+
env:
|
| 25 |
+
- CGO_ENABLED=0
|
| 26 |
+
ldflags:
|
| 27 |
+
- -s -w
|
| 28 |
+
- -X github.com/0xPolygonHermez/zkevm-node.Version={{ .Version }}
|
| 29 |
+
- -X github.com/0xPolygonHermez/zkevm-node.GitRev={{ .Commit }}
|
| 30 |
+
- -X github.com/0xPolygonHermez/zkevm-node.BuildDate={{ .Date }}
|
| 31 |
+
- -X github.com/0xPolygonHermez/zkevm-node.GitBranch={{ .Branch }}
|
| 32 |
+
|
| 33 |
+
archives:
|
| 34 |
+
- files:
|
| 35 |
+
- LICENSE
|
| 36 |
+
- README.md
|
| 37 |
+
|
| 38 |
+
dockers:
|
| 39 |
+
- image_templates:
|
| 40 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-amd64
|
| 41 |
+
dockerfile: Dockerfile.release
|
| 42 |
+
use: buildx
|
| 43 |
+
goos: linux
|
| 44 |
+
goarch: amd64
|
| 45 |
+
build_flag_templates:
|
| 46 |
+
- --platform=linux/amd64
|
| 47 |
+
- --label=org.opencontainers.image.title={{ .ProjectName }}
|
| 48 |
+
- --label=org.opencontainers.image.description={{ .ProjectName }}
|
| 49 |
+
- --label=org.opencontainers.image.url=https://github.com/{{ .ProjectName }}
|
| 50 |
+
- --label=org.opencontainers.image.source=https://github.com/{{ .ProjectName }}
|
| 51 |
+
- --label=org.opencontainers.image.version={{ replace .Version "+" "-" }}
|
| 52 |
+
- --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }}
|
| 53 |
+
- --label=org.opencontainers.image.revision={{ .FullCommit }}
|
| 54 |
+
skip_push: false
|
| 55 |
+
|
| 56 |
+
- image_templates:
|
| 57 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-arm64
|
| 58 |
+
dockerfile: Dockerfile.release
|
| 59 |
+
use: buildx
|
| 60 |
+
goos: linux
|
| 61 |
+
goarch: arm64
|
| 62 |
+
build_flag_templates:
|
| 63 |
+
- --platform=linux/arm64
|
| 64 |
+
- --label=org.opencontainers.image.title={{ .ProjectName }}
|
| 65 |
+
- --label=org.opencontainers.image.description={{ .ProjectName }}
|
| 66 |
+
- --label=org.opencontainers.image.url=https://github.com/{{ .ProjectName }}
|
| 67 |
+
- --label=org.opencontainers.image.source=https://github.com/{{ .ProjectName }}
|
| 68 |
+
- --label=org.opencontainers.image.version={{ replace .Version "+" "-" }}
|
| 69 |
+
- --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }}
|
| 70 |
+
- --label=org.opencontainers.image.revision={{ .FullCommit }}
|
| 71 |
+
skip_push: false
|
| 72 |
+
|
| 73 |
+
docker_manifests:
|
| 74 |
+
- name_template: 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}
|
| 75 |
+
image_templates:
|
| 76 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-amd64
|
| 77 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-arm64
|
| 78 |
+
skip_push: false
|
| 79 |
+
|
| 80 |
+
- name_template: 0xpolygon/{{ .ProjectName }}:latest
|
| 81 |
+
image_templates:
|
| 82 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-amd64
|
| 83 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-arm64
|
| 84 |
+
skip_push: false
|
|
@@ -58,6 +58,46 @@
|
|
| 58 |
return result, nil
|
| 59 |
}
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
// ExitRootsByGER returns the exit roots accordingly to the provided Global Exit Root
|
| 62 |
func (c *Client) ExitRootsByGER(ctx context.Context, globalExitRoot common.Hash) (*types.ExitRoots, error) {
|
| 63 |
response, err := JSONRPCCall(c.url, "zkevm_getExitRootsByGER", globalExitRoot.String())
|
|
|
|
| 58 |
return result, nil
|
| 59 |
}
|
| 60 |
|
| 61 |
+
// BatchesByNumbers returns batches from the current canonical chain by batch numbers. If the list is empty, the last
|
| 62 |
+
// known batch is returned as a list.
|
| 63 |
+
func (c *Client) BatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error) {
|
| 64 |
+
return c.batchesByNumbers(ctx, numbers, "zkevm_getBatchDataByNumbers")
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// ForcedBatchesByNumbers returns forced batches data.
|
| 68 |
+
func (c *Client) ForcedBatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error) {
|
| 69 |
+
return c.batchesByNumbers(ctx, numbers, "zkevm_getForcedBatchDataByNumbers")
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
// BatchesByNumbers returns batches from the current canonical chain by batch numbers. If the list is empty, the last
|
| 73 |
+
// known batch is returned as a list.
|
| 74 |
+
func (c *Client) batchesByNumbers(_ context.Context, numbers []*big.Int, method string) ([]*types.BatchData, error) {
|
| 75 |
+
batchNumbers := make([]types.BatchNumber, 0, len(numbers))
|
| 76 |
+
for _, n := range numbers {
|
| 77 |
+
batchNumbers = append(batchNumbers, types.BatchNumber(n.Int64()))
|
| 78 |
+
}
|
| 79 |
+
if len(batchNumbers) == 0 {
|
| 80 |
+
batchNumbers = append(batchNumbers, types.LatestBatchNumber)
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
response, err := JSONRPCCall(c.url, method, &types.BatchFilter{Numbers: batchNumbers})
|
| 84 |
+
if err != nil {
|
| 85 |
+
return nil, err
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
if response.Error != nil {
|
| 89 |
+
return nil, response.Error.RPCError()
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
var result *types.BatchDataResult
|
| 93 |
+
err = json.Unmarshal(response.Result, &result)
|
| 94 |
+
if err != nil {
|
| 95 |
+
return nil, err
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
return result.Data, nil
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
// ExitRootsByGER returns the exit roots accordingly to the provided Global Exit Root
|
| 102 |
func (c *Client) ExitRootsByGER(ctx context.Context, globalExitRoot common.Hash) (*types.ExitRoots, error) {
|
| 103 |
response, err := JSONRPCCall(c.url, "zkevm_getExitRootsByGER", globalExitRoot.String())
|
|
@@ -104,7 +104,7 @@
|
|
| 104 |
result, err := e.state.ProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, true, dbTx)
|
| 105 |
if err != nil {
|
| 106 |
errMsg := fmt.Sprintf("failed to execute the unsigned transaction: %v", err.Error())
|
| 107 |
-
logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !errors.Is(err, runtime.ErrOutOfGas)
|
| 108 |
return RPCErrorResponse(types.DefaultErrorCode, errMsg, nil, logError)
|
| 109 |
}
|
| 110 |
|
|
@@ -945,6 +945,9 @@
|
|
| 945 |
if e.cfg.SequencerNodeURI != "" {
|
| 946 |
return e.relayTxToSequencerNode(input)
|
| 947 |
} else {
|
|
|
|
|
|
|
|
|
|
| 948 |
ip := ""
|
| 949 |
ips := httpRequest.Header.Get("X-Forwarded-For")
|
| 950 |
|
|
|
|
| 104 |
result, err := e.state.ProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, true, dbTx)
|
| 105 |
if err != nil {
|
| 106 |
errMsg := fmt.Sprintf("failed to execute the unsigned transaction: %v", err.Error())
|
| 107 |
+
logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !(errors.Is(err, runtime.ErrOutOfGas))
|
| 108 |
return RPCErrorResponse(types.DefaultErrorCode, errMsg, nil, logError)
|
| 109 |
}
|
| 110 |
|
|
|
|
| 945 |
if e.cfg.SequencerNodeURI != "" {
|
| 946 |
return e.relayTxToSequencerNode(input)
|
| 947 |
} else {
|
| 948 |
+
if err := checkPolicy(context.Background(), e.pool, input); err != nil {
|
| 949 |
+
return RPCErrorResponse(types.AccessDeniedCode, err.Error(), nil, false)
|
| 950 |
+
}
|
| 951 |
ip := ""
|
| 952 |
ips := httpRequest.Header.Get("X-Forwarded-For")
|
| 953 |
|
|
@@ -6,6 +6,7 @@
|
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
| 8 |
"math/big"
|
|
|
|
| 9 |
"sync"
|
| 10 |
"testing"
|
| 11 |
"time"
|
|
@@ -5416,3 +5417,237 @@
|
|
| 5416 |
assert.ElementsMatch(t, []int{13, 14, 15}, results[4])
|
| 5417 |
assert.ElementsMatch(t, []int{16}, results[5])
|
| 5418 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
| 8 |
"math/big"
|
| 9 |
+
"strings"
|
| 10 |
"sync"
|
| 11 |
"testing"
|
| 12 |
"time"
|
|
|
|
| 5417 |
assert.ElementsMatch(t, []int{13, 14, 15}, results[4])
|
| 5418 |
assert.ElementsMatch(t, []int{16}, results[5])
|
| 5419 |
}
|
| 5420 |
+
|
| 5421 |
+
func TestSendRawTransactionJSONRPCCallWithPolicyApplied(t *testing.T) {
|
| 5422 |
+
// Set up the sender
|
| 5423 |
+
allowedPrivateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x"))
|
| 5424 |
+
require.NoError(t, err)
|
| 5425 |
+
allowed, err := bind.NewKeyedTransactorWithChainID(allowedPrivateKey, big.NewInt(1))
|
| 5426 |
+
require.NoError(t, err)
|
| 5427 |
+
|
| 5428 |
+
disallowedPrivateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0xdeadbeef8721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x"))
|
| 5429 |
+
require.NoError(t, err)
|
| 5430 |
+
disallowed, err := bind.NewKeyedTransactorWithChainID(disallowedPrivateKey, big.NewInt(1))
|
| 5431 |
+
require.NoError(t, err)
|
| 5432 |
+
require.NotNil(t, disallowed)
|
| 5433 |
+
|
| 5434 |
+
allowedContract := common.HexToAddress("0x1")
|
| 5435 |
+
disallowedContract := common.HexToAddress("0x2")
|
| 5436 |
+
|
| 5437 |
+
senderDenied := types.NewRPCError(types.AccessDeniedCode, "sender disallowed send_tx by policy")
|
| 5438 |
+
contractDenied := types.NewRPCError(types.AccessDeniedCode, "contract disallowed send_tx by policy")
|
| 5439 |
+
deployDenied := types.NewRPCError(types.AccessDeniedCode, "sender disallowed deploy by policy")
|
| 5440 |
+
|
| 5441 |
+
cfg := getSequencerDefaultConfig()
|
| 5442 |
+
s, m, _ := newMockedServerWithCustomConfig(t, cfg)
|
| 5443 |
+
defer s.Stop()
|
| 5444 |
+
|
| 5445 |
+
type testCase struct {
|
| 5446 |
+
Name string
|
| 5447 |
+
Input string
|
| 5448 |
+
ExpectedResult *common.Hash
|
| 5449 |
+
ExpectedError types.Error
|
| 5450 |
+
Prepare func(t *testing.T, tc *testCase)
|
| 5451 |
+
SetupMocks func(t *testing.T, m *mocksWrapper, tc testCase)
|
| 5452 |
+
}
|
| 5453 |
+
|
| 5454 |
+
testCases := []testCase{
|
| 5455 |
+
{
|
| 5456 |
+
Name: "Sender & contract on allow list, accepted",
|
| 5457 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5458 |
+
tx := ethTypes.NewTransaction(1, allowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5459 |
+
|
| 5460 |
+
signedTx, err := allowed.Signer(allowed.From, tx)
|
| 5461 |
+
require.NoError(t, err)
|
| 5462 |
+
|
| 5463 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5464 |
+
require.NoError(t, err)
|
| 5465 |
+
|
| 5466 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5467 |
+
require.NoError(t, err)
|
| 5468 |
+
|
| 5469 |
+
tc.Input = rawTx
|
| 5470 |
+
expectedHash := signedTx.Hash()
|
| 5471 |
+
tc.ExpectedResult = &expectedHash
|
| 5472 |
+
tc.ExpectedError = nil
|
| 5473 |
+
},
|
| 5474 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5475 |
+
m.Pool.
|
| 5476 |
+
On("AddTx", context.Background(), mock.IsType(ethTypes.Transaction{}), "").
|
| 5477 |
+
Return(nil).
|
| 5478 |
+
Once()
|
| 5479 |
+
m.Pool.
|
| 5480 |
+
On("CheckPolicy", context.Background(), pool.SendTx, allowedContract).
|
| 5481 |
+
Return(true, nil).
|
| 5482 |
+
Once()
|
| 5483 |
+
m.Pool.
|
| 5484 |
+
On("CheckPolicy", context.Background(), pool.SendTx, allowed.From).
|
| 5485 |
+
Return(true, nil).
|
| 5486 |
+
Once()
|
| 5487 |
+
},
|
| 5488 |
+
},
|
| 5489 |
+
{
|
| 5490 |
+
Name: "Contract not on allow list, rejected",
|
| 5491 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5492 |
+
tx := ethTypes.NewTransaction(1, disallowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5493 |
+
|
| 5494 |
+
signedTx, err := allowed.Signer(allowed.From, tx)
|
| 5495 |
+
require.NoError(t, err)
|
| 5496 |
+
|
| 5497 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5498 |
+
require.NoError(t, err)
|
| 5499 |
+
|
| 5500 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5501 |
+
require.NoError(t, err)
|
| 5502 |
+
|
| 5503 |
+
tc.Input = rawTx
|
| 5504 |
+
tc.ExpectedResult = nil
|
| 5505 |
+
tc.ExpectedError = contractDenied
|
| 5506 |
+
},
|
| 5507 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5508 |
+
m.Pool.
|
| 5509 |
+
On("CheckPolicy", context.Background(), pool.SendTx, disallowedContract).
|
| 5510 |
+
Return(false, contractDenied).
|
| 5511 |
+
Once()
|
| 5512 |
+
},
|
| 5513 |
+
},
|
| 5514 |
+
{
|
| 5515 |
+
Name: "Sender not on allow list, rejected",
|
| 5516 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5517 |
+
tx := ethTypes.NewTransaction(1, allowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5518 |
+
|
| 5519 |
+
signedTx, err := disallowed.Signer(disallowed.From, tx)
|
| 5520 |
+
require.NoError(t, err)
|
| 5521 |
+
|
| 5522 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5523 |
+
require.NoError(t, err)
|
| 5524 |
+
|
| 5525 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5526 |
+
require.NoError(t, err)
|
| 5527 |
+
|
| 5528 |
+
tc.Input = rawTx
|
| 5529 |
+
tc.ExpectedResult = nil
|
| 5530 |
+
tc.ExpectedError = senderDenied
|
| 5531 |
+
},
|
| 5532 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5533 |
+
m.Pool.
|
| 5534 |
+
On("CheckPolicy", context.Background(), pool.SendTx, allowedContract).
|
| 5535 |
+
Return(true, nil).
|
| 5536 |
+
Once()
|
| 5537 |
+
m.Pool.
|
| 5538 |
+
On("CheckPolicy", context.Background(), pool.SendTx, disallowed.From).
|
| 5539 |
+
Return(false, senderDenied).
|
| 5540 |
+
Once()
|
| 5541 |
+
},
|
| 5542 |
+
},
|
| 5543 |
+
{
|
| 5544 |
+
Name: "Unsigned tx with allowed contract, accepted", // for backward compatibility
|
| 5545 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5546 |
+
tx := ethTypes.NewTransaction(1, allowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5547 |
+
|
| 5548 |
+
txBinary, err := tx.MarshalBinary()
|
| 5549 |
+
require.NoError(t, err)
|
| 5550 |
+
|
| 5551 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5552 |
+
require.NoError(t, err)
|
| 5553 |
+
|
| 5554 |
+
tc.Input = rawTx
|
| 5555 |
+
expectedHash := tx.Hash()
|
| 5556 |
+
tc.ExpectedResult = &expectedHash
|
| 5557 |
+
tc.ExpectedError = nil
|
| 5558 |
+
},
|
| 5559 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5560 |
+
m.Pool.
|
| 5561 |
+
On("AddTx", context.Background(), mock.IsType(ethTypes.Transaction{}), "").
|
| 5562 |
+
Return(nil).
|
| 5563 |
+
Once()
|
| 5564 |
+
// policy does not reject this case for backward compat
|
| 5565 |
+
},
|
| 5566 |
+
},
|
| 5567 |
+
{
|
| 5568 |
+
Name: "Unsigned tx with disallowed contract, rejected",
|
| 5569 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5570 |
+
tx := ethTypes.NewTransaction(1, disallowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5571 |
+
|
| 5572 |
+
signedTx, err := disallowed.Signer(disallowed.From, tx)
|
| 5573 |
+
require.NoError(t, err)
|
| 5574 |
+
|
| 5575 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5576 |
+
require.NoError(t, err)
|
| 5577 |
+
|
| 5578 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5579 |
+
require.NoError(t, err)
|
| 5580 |
+
|
| 5581 |
+
tc.Input = rawTx
|
| 5582 |
+
tc.ExpectedResult = nil
|
| 5583 |
+
tc.ExpectedError = contractDenied
|
| 5584 |
+
},
|
| 5585 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5586 |
+
m.Pool.
|
| 5587 |
+
On("CheckPolicy", context.Background(), pool.SendTx, disallowedContract).
|
| 5588 |
+
Return(false, contractDenied).
|
| 5589 |
+
Once()
|
| 5590 |
+
},
|
| 5591 |
+
},
|
| 5592 |
+
{
|
| 5593 |
+
Name: "Send invalid tx input", // for backward compatibility
|
| 5594 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5595 |
+
tc.Input = "0x1234"
|
| 5596 |
+
tc.ExpectedResult = nil
|
| 5597 |
+
tc.ExpectedError = types.NewRPCError(types.InvalidParamsErrorCode, "invalid tx input")
|
| 5598 |
+
},
|
| 5599 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {},
|
| 5600 |
+
},
|
| 5601 |
+
{
|
| 5602 |
+
Name: "Sender not on deploy allow list, rejected",
|
| 5603 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5604 |
+
deployAddr := common.HexToAddress("0x0")
|
| 5605 |
+
tx := ethTypes.NewTransaction(1, deployAddr, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5606 |
+
|
| 5607 |
+
signedTx, err := disallowed.Signer(disallowed.From, tx)
|
| 5608 |
+
require.NoError(t, err)
|
| 5609 |
+
|
| 5610 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5611 |
+
require.NoError(t, err)
|
| 5612 |
+
|
| 5613 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5614 |
+
require.NoError(t, err)
|
| 5615 |
+
|
| 5616 |
+
tc.Input = rawTx
|
| 5617 |
+
tc.ExpectedResult = nil
|
| 5618 |
+
tc.ExpectedError = deployDenied
|
| 5619 |
+
},
|
| 5620 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5621 |
+
m.Pool.
|
| 5622 |
+
On("CheckPolicy", context.Background(), pool.Deploy, disallowed.From).
|
| 5623 |
+
Return(false, nil).
|
| 5624 |
+
Once()
|
| 5625 |
+
},
|
| 5626 |
+
},
|
| 5627 |
+
}
|
| 5628 |
+
|
| 5629 |
+
for _, testCase := range testCases {
|
| 5630 |
+
t.Run(testCase.Name, func(t *testing.T) {
|
| 5631 |
+
tc := testCase
|
| 5632 |
+
tc.Prepare(t, &tc)
|
| 5633 |
+
tc.SetupMocks(t, m, tc)
|
| 5634 |
+
|
| 5635 |
+
res, err := s.JSONRPCCall("eth_sendRawTransaction", tc.Input)
|
| 5636 |
+
require.NoError(t, err)
|
| 5637 |
+
|
| 5638 |
+
assert.Equal(t, float64(1), res.ID)
|
| 5639 |
+
assert.Equal(t, "2.0", res.JSONRPC)
|
| 5640 |
+
|
| 5641 |
+
if res.Result != nil || tc.ExpectedResult != nil {
|
| 5642 |
+
var result common.Hash
|
| 5643 |
+
err = json.Unmarshal(res.Result, &result)
|
| 5644 |
+
require.NoError(t, err)
|
| 5645 |
+
assert.Equal(t, *tc.ExpectedResult, result)
|
| 5646 |
+
}
|
| 5647 |
+
if res.Error != nil || tc.ExpectedError != nil {
|
| 5648 |
+
assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
|
| 5649 |
+
assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
|
| 5650 |
+
}
|
| 5651 |
+
})
|
| 5652 |
+
}
|
| 5653 |
+
}
|
|
@@ -204,6 +204,53 @@
|
|
| 204 |
})
|
| 205 |
}
|
| 206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
// GetFullBlockByNumber returns information about a block by block number
|
| 208 |
func (z *ZKEVMEndpoints) GetFullBlockByNumber(number types.BlockNumber, fullTx bool) (interface{}, types.Error) {
|
| 209 |
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
|
@@ -516,7 +563,7 @@
|
|
| 516 |
|
| 517 |
if txEGP.Cmp(txGasPrice) == -1 { // txEGP < txGasPrice
|
| 518 |
// We need to "round" the final effectiveGasPrice to a 256 fraction of the txGasPrice
|
| 519 |
-
txEGPPct, err =
|
| 520 |
if err != nil {
|
| 521 |
return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to calculate effective gas price percentage", err, false)
|
| 522 |
}
|
|
|
|
| 204 |
})
|
| 205 |
}
|
| 206 |
|
| 207 |
+
type batchDataFunc func(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 208 |
+
|
| 209 |
+
// GetBatchDataByNumbers returns L2 batch data by batch numbers.
|
| 210 |
+
func (z *ZKEVMEndpoints) GetBatchDataByNumbers(filter types.BatchFilter) (interface{}, types.Error) {
|
| 211 |
+
return z.getBatchData(filter, z.state.GetBatchL2DataByNumbers)
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
// GetForcedBatchDataByNumbers returns forced batch data by batch numbers.
|
| 215 |
+
func (z *ZKEVMEndpoints) GetForcedBatchDataByNumbers(filter types.BatchFilter) (interface{}, types.Error) {
|
| 216 |
+
return z.getBatchData(filter, z.state.GetForcedBatchDataByNumbers)
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
func (z *ZKEVMEndpoints) getBatchData(filter types.BatchFilter, f batchDataFunc) (interface{}, types.Error) {
|
| 220 |
+
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
| 221 |
+
batchNumbers := make([]uint64, 0, len(filter.Numbers))
|
| 222 |
+
for _, bn := range filter.Numbers {
|
| 223 |
+
n, rpcErr := bn.GetNumericBatchNumber(ctx, z.state, z.etherman, dbTx)
|
| 224 |
+
if rpcErr != nil {
|
| 225 |
+
return nil, rpcErr
|
| 226 |
+
}
|
| 227 |
+
batchNumbers = append(batchNumbers, n)
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
batchesData, err := f(ctx, batchNumbers, dbTx)
|
| 231 |
+
if errors.Is(err, state.ErrNotFound) {
|
| 232 |
+
return nil, nil
|
| 233 |
+
} else if err != nil {
|
| 234 |
+
return RPCErrorResponse(types.DefaultErrorCode,
|
| 235 |
+
fmt.Sprintf("couldn't load batch data from state by numbers %v", filter.Numbers), err, true)
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
ret := make([]*types.BatchData, 0, len(batchNumbers))
|
| 239 |
+
for _, n := range batchNumbers {
|
| 240 |
+
data := &types.BatchData{Number: types.ArgUint64(n)}
|
| 241 |
+
if b, ok := batchesData[n]; ok {
|
| 242 |
+
data.BatchL2Data = b
|
| 243 |
+
data.Empty = false
|
| 244 |
+
} else {
|
| 245 |
+
data.Empty = true
|
| 246 |
+
}
|
| 247 |
+
ret = append(ret, data)
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
return types.BatchDataResult{Data: ret}, nil
|
| 251 |
+
})
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
// GetFullBlockByNumber returns information about a block by block number
|
| 255 |
func (z *ZKEVMEndpoints) GetFullBlockByNumber(number types.BlockNumber, fullTx bool) (interface{}, types.Error) {
|
| 256 |
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
|
|
|
| 563 |
|
| 564 |
if txEGP.Cmp(txGasPrice) == -1 { // txEGP < txGasPrice
|
| 565 |
// We need to "round" the final effectiveGasPrice to a 256 fraction of the txGasPrice
|
| 566 |
+
txEGPPct, err = state.CalculateEffectiveGasPricePercentage(txGasPrice, txEGP)
|
| 567 |
if err != nil {
|
| 568 |
return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to calculate effective gas price percentage", err, false)
|
| 569 |
}
|
|
@@ -2705,3 +2705,32 @@
|
|
| 2705 |
})
|
| 2706 |
}
|
| 2707 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2705 |
})
|
| 2706 |
}
|
| 2707 |
}
|
| 2708 |
+
|
| 2709 |
+
func TestClient_BatchesByNumbers(t *testing.T) {
|
| 2710 |
+
const batchesCount = 6
|
| 2711 |
+
|
| 2712 |
+
s, m, _ := newSequencerMockedServer(t)
|
| 2713 |
+
defer s.Stop()
|
| 2714 |
+
|
| 2715 |
+
batchesDataMap := make(map[uint64][]byte, batchesCount)
|
| 2716 |
+
for i := 0; i < batchesCount; i++ {
|
| 2717 |
+
batchesDataMap[uint64(i+1)] = []byte(fmt.Sprintf("batch %d data", i+1))
|
| 2718 |
+
}
|
| 2719 |
+
|
| 2720 |
+
m.State.On("GetBatchL2DataByNumbers", mock.Anything, mock.Anything, mock.Anything).
|
| 2721 |
+
Return(batchesDataMap, nil).Once()
|
| 2722 |
+
|
| 2723 |
+
m.State.On("BeginStateTransaction", context.Background()).
|
| 2724 |
+
Return(m.DbTx, nil).Once()
|
| 2725 |
+
|
| 2726 |
+
m.DbTx.On("Commit", context.Background()).Return(nil).Once()
|
| 2727 |
+
|
| 2728 |
+
zkEVMClient := client.NewClient(s.ServerURL)
|
| 2729 |
+
reqBatchesNum := []*big.Int{big.NewInt(1), big.NewInt(3), big.NewInt(4)}
|
| 2730 |
+
result, err := zkEVMClient.BatchesByNumbers(context.Background(), reqBatchesNum)
|
| 2731 |
+
require.NoError(t, err)
|
| 2732 |
+
require.Len(t, result, len(reqBatchesNum))
|
| 2733 |
+
for i, batchNum := range reqBatchesNum {
|
| 2734 |
+
require.Equal(t, hex.EncodeToHex(batchesDataMap[batchNum.Uint64()]), result[i].BatchL2Data.Hex())
|
| 2735 |
+
}
|
| 2736 |
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package jsonrpc
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
|
| 6 |
+
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/pool"
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
+
"github.com/ethereum/go-ethereum/common"
|
| 10 |
+
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
func checkPolicy(ctx context.Context, p types.PoolInterface, input string) error {
|
| 14 |
+
tx, err := hexToTx(input)
|
| 15 |
+
if err != nil {
|
| 16 |
+
// ignore it, let the later processing reject
|
| 17 |
+
return nil
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
// if the tx is signed, check the from address. If there is no from address, the tx is not rejected as it
|
| 21 |
+
// will get rejected later. This maintains backward compatibility with RPC expectations. TODO: verify this is ok behavior
|
| 22 |
+
var from common.Address
|
| 23 |
+
if from, err = state.GetSender(*tx); err != nil {
|
| 24 |
+
// if not signed, then skip check, it fails later on its own
|
| 25 |
+
return nil
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
switch resolvePolicy(tx) {
|
| 29 |
+
case pool.SendTx:
|
| 30 |
+
var allow bool
|
| 31 |
+
if allow, err = p.CheckPolicy(ctx, pool.SendTx, *tx.To()); err != nil {
|
| 32 |
+
return err
|
| 33 |
+
}
|
| 34 |
+
if !allow {
|
| 35 |
+
return pool.ErrContractDisallowedSendTx
|
| 36 |
+
}
|
| 37 |
+
if allow, err = p.CheckPolicy(ctx, pool.SendTx, from); err != nil {
|
| 38 |
+
return err
|
| 39 |
+
}
|
| 40 |
+
if !allow {
|
| 41 |
+
return pool.ErrSenderDisallowedSendTx
|
| 42 |
+
}
|
| 43 |
+
case pool.Deploy:
|
| 44 |
+
var allow bool
|
| 45 |
+
// check that sender may deploy contracts
|
| 46 |
+
if allow, err = p.CheckPolicy(ctx, pool.Deploy, from); err != nil {
|
| 47 |
+
return err
|
| 48 |
+
}
|
| 49 |
+
if !allow {
|
| 50 |
+
return pool.ErrSenderDisallowedDeploy
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
return nil
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
func resolvePolicy(tx *ethTypes.Transaction) pool.PolicyName {
|
| 57 |
+
if tx.To() == nil || tx.To().Hex() == common.HexToAddress("0x0").Hex() {
|
| 58 |
+
return pool.Deploy
|
| 59 |
+
}
|
| 60 |
+
return pool.SendTx
|
| 61 |
+
}
|
|
@@ -15,6 +15,8 @@
|
|
| 15 |
InvalidParamsErrorCode = -32602
|
| 16 |
// ParserErrorCode error code for parsing errors
|
| 17 |
ParserErrorCode = -32700
|
|
|
|
|
|
|
| 18 |
)
|
| 19 |
|
| 20 |
var (
|
|
|
|
| 15 |
InvalidParamsErrorCode = -32602
|
| 16 |
// ParserErrorCode error code for parsing errors
|
| 17 |
ParserErrorCode = -32700
|
| 18 |
+
// AccessDeniedCode error code when requests are denied
|
| 19 |
+
AccessDeniedCode = -32800
|
| 20 |
)
|
| 21 |
|
| 22 |
var (
|
|
@@ -23,8 +23,8 @@
|
|
| 23 |
CountPendingTransactions(ctx context.Context) (uint64, error)
|
| 24 |
GetTransactionByHash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
| 25 |
GetTransactionByL2Hash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
|
|
|
| 26 |
CalculateEffectiveGasPrice(rawTx []byte, txGasPrice *big.Int, txGasUsed uint64, l1GasPrice uint64, l2GasPrice uint64) (*big.Int, error)
|
| 27 |
-
CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error)
|
| 28 |
EffectiveGasPriceEnabled() bool
|
| 29 |
}
|
| 30 |
|
|
@@ -64,6 +64,8 @@
|
|
| 64 |
GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
| 65 |
GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 66 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
|
|
|
|
|
|
| 67 |
GetTransactionsByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (txs []types.Transaction, effectivePercentages []uint8, err error)
|
| 68 |
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
|
| 69 |
GetVerifiedBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
|
|
|
| 23 |
CountPendingTransactions(ctx context.Context) (uint64, error)
|
| 24 |
GetTransactionByHash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
| 25 |
GetTransactionByL2Hash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
| 26 |
+
CheckPolicy(ctx context.Context, policy pool.PolicyName, address common.Address) (bool, error)
|
| 27 |
CalculateEffectiveGasPrice(rawTx []byte, txGasPrice *big.Int, txGasUsed uint64, l1GasPrice uint64, l2GasPrice uint64) (*big.Int, error)
|
|
|
|
| 28 |
EffectiveGasPriceEnabled() bool
|
| 29 |
}
|
| 30 |
|
|
|
|
| 64 |
GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
| 65 |
GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 66 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 67 |
+
GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 68 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 69 |
GetTransactionsByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (txs []types.Transaction, effectivePercentages []uint8, err error)
|
| 70 |
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
|
| 71 |
GetVerifiedBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
|
@@ -446,6 +446,23 @@
|
|
| 446 |
return res, nil
|
| 447 |
}
|
| 448 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
// TransactionOrHash for union type of transaction and types.Hash
|
| 450 |
type TransactionOrHash struct {
|
| 451 |
Hash *common.Hash
|
|
|
|
| 446 |
return res, nil
|
| 447 |
}
|
| 448 |
|
| 449 |
+
// BatchFilter is a list of batch numbers to retrieve
|
| 450 |
+
type BatchFilter struct {
|
| 451 |
+
Numbers []BatchNumber `json:"numbers"`
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
// BatchData is an abbreviated structure that only contains the number and L2 batch data
|
| 455 |
+
type BatchData struct {
|
| 456 |
+
Number ArgUint64 `json:"number"`
|
| 457 |
+
BatchL2Data ArgBytes `json:"batchL2Data,omitempty"`
|
| 458 |
+
Empty bool `json:"empty"`
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
// BatchDataResult is a list of BatchData for a BatchFilter
|
| 462 |
+
type BatchDataResult struct {
|
| 463 |
+
Data []*BatchData `json:"data"`
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
// TransactionOrHash for union type of transaction and types.Hash
|
| 467 |
type TransactionOrHash struct {
|
| 468 |
Hash *common.Hash
|
|
@@ -192,11 +192,6 @@
|
|
| 192 |
return mt.ComputeMerkleProof(mt.count, initialLeaves)
|
| 193 |
}
|
| 194 |
|
| 195 |
-
// GetRoot returns the root of the L1InfoTree
|
| 196 |
-
func (mt *L1InfoTree) GetRoot() common.Hash {
|
| 197 |
-
return mt.currentRoot
|
| 198 |
-
}
|
| 199 |
-
|
| 200 |
// GetCurrentRootCountAndSiblings returns the latest root, count and sibblings
|
| 201 |
func (mt *L1InfoTree) GetCurrentRootCountAndSiblings() (common.Hash, uint32, [][32]byte) {
|
| 202 |
return mt.currentRoot, mt.count, mt.siblings
|
|
|
|
| 192 |
return mt.ComputeMerkleProof(mt.count, initialLeaves)
|
| 193 |
}
|
| 194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
// GetCurrentRootCountAndSiblings returns the latest root, count and sibblings
|
| 196 |
func (mt *L1InfoTree) GetCurrentRootCountAndSiblings() (common.Hash, uint32, [][32]byte) {
|
| 197 |
return mt.currentRoot, mt.count, mt.siblings
|
|
@@ -1,94 +0,0 @@
|
|
| 1 |
-
package l1infotree
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"github.com/ethereum/go-ethereum/common"
|
| 5 |
-
"github.com/ethereum/go-ethereum/crypto"
|
| 6 |
-
)
|
| 7 |
-
|
| 8 |
-
const (
|
| 9 |
-
emptyHistoricL1InfoTreeRoot = "0x27ae5ba08d7291c96c8cbddcc148bf48a6d68c7974b94356f53754ef6171d757"
|
| 10 |
-
)
|
| 11 |
-
|
| 12 |
-
// L1InfoTreeRecursive is a recursive implementation of the L1InfoTree of Feijoa
|
| 13 |
-
type L1InfoTreeRecursive struct {
|
| 14 |
-
historicL1InfoTree *L1InfoTree
|
| 15 |
-
currentLeaf common.Hash
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
// L1InfoTreeRecursiveSnapshot provides the information generated when a new
|
| 19 |
-
// leaf is added to the tree
|
| 20 |
-
type L1InfoTreeRecursiveSnapshot struct {
|
| 21 |
-
HistoricL1InfoTreeRoot common.Hash
|
| 22 |
-
L1Data common.Hash
|
| 23 |
-
L1InfoTreeRoot common.Hash
|
| 24 |
-
}
|
| 25 |
-
|
| 26 |
-
// NewL1InfoTreeRecursive creates a new empty L1InfoTreeRecursive
|
| 27 |
-
func NewL1InfoTreeRecursive(height uint8) (*L1InfoTreeRecursive, error) {
|
| 28 |
-
historic, err := NewL1InfoTree(height, nil)
|
| 29 |
-
if err != nil {
|
| 30 |
-
return nil, err
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
mtr := &L1InfoTreeRecursive{
|
| 34 |
-
historicL1InfoTree: historic,
|
| 35 |
-
currentLeaf: common.Hash{},
|
| 36 |
-
}
|
| 37 |
-
return mtr, nil
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
// NewL1InfoTreeRecursiveFromLeaves creates a new L1InfoTreeRecursive from leaves as they are
|
| 41 |
-
func NewL1InfoTreeRecursiveFromLeaves(height uint8, leaves [][32]byte) (*L1InfoTreeRecursive, error) {
|
| 42 |
-
mtr, err := NewL1InfoTreeRecursive(height)
|
| 43 |
-
if err != nil {
|
| 44 |
-
return nil, err
|
| 45 |
-
}
|
| 46 |
-
|
| 47 |
-
for i, leaf := range leaves {
|
| 48 |
-
_, err := mtr.AddLeaf(uint32(i), leaf)
|
| 49 |
-
if err != nil {
|
| 50 |
-
return nil, err
|
| 51 |
-
}
|
| 52 |
-
mtr.currentLeaf = leaf
|
| 53 |
-
}
|
| 54 |
-
return mtr, nil
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
// AddLeaf hashes the current historicL1InfoRoot + currentLeaf data into the new historicLeaf value,
|
| 58 |
-
// then adds it to the historicL1InfoTree and finally stores the new leaf as the currentLeaf
|
| 59 |
-
func (mt *L1InfoTreeRecursive) AddLeaf(index uint32, leaf [32]byte) (common.Hash, error) {
|
| 60 |
-
// adds the current l1InfoTreeRoot into the historic tree to generate
|
| 61 |
-
// the next historicL2InfoTreeRoot
|
| 62 |
-
l1InfoTreeRoot := mt.GetRoot()
|
| 63 |
-
_, err := mt.historicL1InfoTree.AddLeaf(index, l1InfoTreeRoot)
|
| 64 |
-
if err != nil {
|
| 65 |
-
return common.Hash{}, err
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
mt.currentLeaf = leaf
|
| 69 |
-
|
| 70 |
-
return mt.GetRoot(), nil
|
| 71 |
-
}
|
| 72 |
-
|
| 73 |
-
// GetRoot returns the root of the L1InfoTreeRecursive
|
| 74 |
-
func (mt *L1InfoTreeRecursive) GetRoot() common.Hash {
|
| 75 |
-
// if the historicL1InfoTree is empty and the the current leaf is also empty
|
| 76 |
-
// returns the root as all zeros 0x0000...0000
|
| 77 |
-
if mt.historicL1InfoTree.GetRoot().String() == emptyHistoricL1InfoTreeRoot &&
|
| 78 |
-
mt.currentLeaf.Cmp(common.Hash{}) == 0 {
|
| 79 |
-
return common.Hash{}
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
l1InfoTreeRoot := crypto.Keccak256Hash(mt.historicL1InfoTree.GetRoot().Bytes(), mt.currentLeaf[:])
|
| 83 |
-
return l1InfoTreeRoot
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
// GetHistoricRoot returns the root of the HistoricL1InfoTree
|
| 87 |
-
func (mt *L1InfoTreeRecursive) GetHistoricRoot() common.Hash {
|
| 88 |
-
return mt.historicL1InfoTree.GetRoot()
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
// ComputeMerkleProof computes the Merkle proof from the leaves
|
| 92 |
-
func (mt *L1InfoTreeRecursive) ComputeMerkleProof(gerIndex uint32, leaves [][32]byte) ([][32]byte, common.Hash, error) {
|
| 93 |
-
return mt.historicL1InfoTree.ComputeMerkleProof(gerIndex, leaves)
|
| 94 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,113 +0,0 @@
|
|
| 1 |
-
package l1infotree_test
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"encoding/json"
|
| 5 |
-
"os"
|
| 6 |
-
"strconv"
|
| 7 |
-
"testing"
|
| 8 |
-
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/l1infotree"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
-
"github.com/ethereum/go-ethereum/common"
|
| 12 |
-
"github.com/stretchr/testify/assert"
|
| 13 |
-
"github.com/stretchr/testify/require"
|
| 14 |
-
)
|
| 15 |
-
|
| 16 |
-
const (
|
| 17 |
-
l1InfoRootRecursiveHeight = uint8(32)
|
| 18 |
-
emptyL1InfoTreeRecursiveRoot = "0x27ae5ba08d7291c96c8cbddcc148bf48a6d68c7974b94356f53754ef6171d757"
|
| 19 |
-
filenameTestData = "../test/vectors/src/merkle-tree/l1-info-tree-recursive/smt-full-output.json"
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
type vectorTestData struct {
|
| 23 |
-
GlobalExitRoot common.Hash `json:"globalExitRoot"`
|
| 24 |
-
BlockHash common.Hash `json:"blockHash"`
|
| 25 |
-
MinTimestamp string `json:"minTimestamp"`
|
| 26 |
-
SmtProof []common.Hash `json:"smtProof"`
|
| 27 |
-
Index uint32 `json:"index"`
|
| 28 |
-
PreviousIndex uint32 `json:"previousIndex"`
|
| 29 |
-
PreviousL1InfoTreeRoot common.Hash `json:"previousL1InfoTreeRoot"`
|
| 30 |
-
L1DataHash common.Hash `json:"l1DataHash"`
|
| 31 |
-
L1InfoTreeRoot common.Hash `json:"l1InfoTreeRoot"`
|
| 32 |
-
HistoricL1InfoRoot common.Hash `json:"historicL1InfoRoot"`
|
| 33 |
-
}
|
| 34 |
-
|
| 35 |
-
func readData(t *testing.T) []vectorTestData {
|
| 36 |
-
data, err := os.ReadFile(filenameTestData)
|
| 37 |
-
require.NoError(t, err)
|
| 38 |
-
var mtTestVectors []vectorTestData
|
| 39 |
-
err = json.Unmarshal(data, &mtTestVectors)
|
| 40 |
-
require.NoError(t, err)
|
| 41 |
-
return mtTestVectors
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
func TestEmptyL1InfoRootRecursive(t *testing.T) {
|
| 45 |
-
mtr, err := l1infotree.NewL1InfoTreeRecursive(l1InfoRootRecursiveHeight)
|
| 46 |
-
require.NoError(t, err)
|
| 47 |
-
require.NotNil(t, mtr)
|
| 48 |
-
root := mtr.GetRoot()
|
| 49 |
-
require.Equal(t, common.Hash{}.String(), root.String())
|
| 50 |
-
}
|
| 51 |
-
|
| 52 |
-
func TestEmptyHistoricL1InfoRootRecursive(t *testing.T) {
|
| 53 |
-
mtr, err := l1infotree.NewL1InfoTreeRecursive(l1InfoRootRecursiveHeight)
|
| 54 |
-
require.NoError(t, err)
|
| 55 |
-
require.NotNil(t, mtr)
|
| 56 |
-
root := mtr.GetHistoricRoot()
|
| 57 |
-
require.Equal(t, emptyL1InfoTreeRecursiveRoot, root.String())
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
func TestBuildTreeVectorData(t *testing.T) {
|
| 61 |
-
data := readData(t)
|
| 62 |
-
mtr, err := l1infotree.NewL1InfoTreeRecursive(l1InfoRootRecursiveHeight)
|
| 63 |
-
require.NoError(t, err)
|
| 64 |
-
for _, testVector := range data {
|
| 65 |
-
minTimestamp, err := strconv.ParseUint(testVector.MinTimestamp, 10, 0)
|
| 66 |
-
require.NoError(t, err)
|
| 67 |
-
l1Data := l1infotree.HashLeafData(testVector.GlobalExitRoot, testVector.BlockHash, minTimestamp)
|
| 68 |
-
l1DataHash := common.BytesToHash(l1Data[:])
|
| 69 |
-
assert.Equal(t, testVector.L1DataHash.String(), l1DataHash.String(), "l1Data doesn't match leaf", testVector.Index)
|
| 70 |
-
|
| 71 |
-
l1InfoTreeRoot, err := mtr.AddLeaf(testVector.Index-1, l1Data)
|
| 72 |
-
require.NoError(t, err)
|
| 73 |
-
assert.Equal(t, testVector.L1InfoTreeRoot.String(), l1InfoTreeRoot.String(), "l1InfoTreeRoot doesn't match leaf", testVector.Index)
|
| 74 |
-
assert.Equal(t, testVector.L1InfoTreeRoot.String(), mtr.GetRoot().String(), "l1InfoTreeRoot doesn't match leaf", testVector.Index)
|
| 75 |
-
assert.Equal(t, testVector.HistoricL1InfoRoot.String(), mtr.GetHistoricRoot().String(), "HistoricL1InfoTreeRoot doesn't match leaf", testVector.Index)
|
| 76 |
-
}
|
| 77 |
-
}
|
| 78 |
-
|
| 79 |
-
func TestBuildTreeFromLeaves(t *testing.T) {
|
| 80 |
-
data := readData(t)
|
| 81 |
-
|
| 82 |
-
leaves := [][32]byte{}
|
| 83 |
-
for _, testVector := range data {
|
| 84 |
-
leaves = append(leaves, testVector.L1DataHash)
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
newMtr, err := l1infotree.NewL1InfoTreeRecursiveFromLeaves(l1InfoRootRecursiveHeight, leaves)
|
| 88 |
-
require.NoError(t, err)
|
| 89 |
-
assert.Equal(t, data[len(data)-1].L1InfoTreeRoot.String(), newMtr.GetRoot().String(), "L1InfoTreeRoot doesn't match leaf")
|
| 90 |
-
}
|
| 91 |
-
|
| 92 |
-
func TestProofsTreeVectorData(t *testing.T) {
|
| 93 |
-
data := readData(t)
|
| 94 |
-
mtr, err := l1infotree.NewL1InfoTreeRecursive(l1InfoRootRecursiveHeight)
|
| 95 |
-
require.NoError(t, err)
|
| 96 |
-
|
| 97 |
-
leaves := [][32]byte{}
|
| 98 |
-
for _, testVector := range data {
|
| 99 |
-
l1InfoTreeRoot, err := mtr.AddLeaf(testVector.Index-1, testVector.L1DataHash)
|
| 100 |
-
require.NoError(t, err)
|
| 101 |
-
|
| 102 |
-
leaves = append(leaves, l1InfoTreeRoot)
|
| 103 |
-
|
| 104 |
-
mp, _, err := mtr.ComputeMerkleProof(testVector.Index, leaves)
|
| 105 |
-
require.NoError(t, err)
|
| 106 |
-
for i, v := range mp {
|
| 107 |
-
c := common.Hash(v)
|
| 108 |
-
if c.String() != testVector.SmtProof[i].String() {
|
| 109 |
-
log.Info("MerkleProof: index ", testVector.Index, " mk:", i, " v:", c.String(), " expected:", testVector.SmtProof[i].String())
|
| 110 |
-
}
|
| 111 |
-
}
|
| 112 |
-
}
|
| 113 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -7,7 +7,6 @@
|
|
| 7 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/merkletree/hashdb"
|
| 9 |
"google.golang.org/grpc"
|
| 10 |
-
"google.golang.org/grpc/connectivity"
|
| 11 |
"google.golang.org/grpc/credentials/insecure"
|
| 12 |
)
|
| 13 |
|
|
@@ -15,37 +14,18 @@
|
|
| 15 |
func NewMTDBServiceClient(ctx context.Context, c Config) (hashdb.HashDBServiceClient, *grpc.ClientConn, context.CancelFunc) {
|
| 16 |
opts := []grpc.DialOption{
|
| 17 |
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
|
|
| 18 |
}
|
| 19 |
-
|
| 20 |
-
mtDBConn, err := grpc.NewClient(c.URI, opts...)
|
| 21 |
-
if err != nil {
|
| 22 |
-
log.Fatalf("fail to create grpc connection to merkletree: %v", err)
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
log.Infof("trying to connect to merkletree: %v", c.URI)
|
| 26 |
const maxWaitSeconds = 120
|
| 27 |
ctx, cancel := context.WithTimeout(ctx, maxWaitSeconds*time.Second)
|
| 28 |
-
|
| 29 |
-
|
|
|
|
| 30 |
if err != nil {
|
| 31 |
-
log.Fatalf("fail to
|
| 32 |
}
|
| 33 |
log.Infof("connected to merkletree")
|
| 34 |
|
| 35 |
mtDBClient := hashdb.NewHashDBServiceClient(mtDBConn)
|
| 36 |
return mtDBClient, mtDBConn, cancel
|
| 37 |
}
|
| 38 |
-
|
| 39 |
-
func waitForConnection(ctx context.Context, conn *grpc.ClientConn) error {
|
| 40 |
-
for {
|
| 41 |
-
select {
|
| 42 |
-
case <-ctx.Done():
|
| 43 |
-
return ctx.Err()
|
| 44 |
-
case <-time.After(time.Second):
|
| 45 |
-
s := conn.GetState()
|
| 46 |
-
if s == connectivity.Ready {
|
| 47 |
-
return nil
|
| 48 |
-
}
|
| 49 |
-
}
|
| 50 |
-
}
|
| 51 |
-
}
|
|
|
|
| 7 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/merkletree/hashdb"
|
| 9 |
"google.golang.org/grpc"
|
|
|
|
| 10 |
"google.golang.org/grpc/credentials/insecure"
|
| 11 |
)
|
| 12 |
|
|
|
|
| 14 |
func NewMTDBServiceClient(ctx context.Context, c Config) (hashdb.HashDBServiceClient, *grpc.ClientConn, context.CancelFunc) {
|
| 15 |
opts := []grpc.DialOption{
|
| 16 |
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
| 17 |
+
grpc.WithBlock(),
|
| 18 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
const maxWaitSeconds = 120
|
| 20 |
ctx, cancel := context.WithTimeout(ctx, maxWaitSeconds*time.Second)
|
| 21 |
+
|
| 22 |
+
log.Infof("trying to connect to merkletree: %v", c.URI)
|
| 23 |
+
mtDBConn, err := grpc.DialContext(ctx, c.URI, opts...)
|
| 24 |
if err != nil {
|
| 25 |
+
log.Fatalf("fail to dial: %v", err)
|
| 26 |
}
|
| 27 |
log.Infof("connected to merkletree")
|
| 28 |
|
| 29 |
mtDBClient := hashdb.NewHashDBServiceClient(mtDBConn)
|
| 30 |
return mtDBClient, mtDBConn, cancel
|
| 31 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -93,9 +93,6 @@
|
|
| 93 |
}
|
| 94 |
|
| 95 |
k := new(big.Int).SetBytes(scCodeHash)
|
| 96 |
-
if k.Cmp(big.NewInt(0)) == 0 {
|
| 97 |
-
return []byte{}, nil
|
| 98 |
-
}
|
| 99 |
|
| 100 |
// this code gets actual smart contract code from sc code storage
|
| 101 |
scCode, err := tree.getProgram(ctx, scalarToh4(k))
|
|
|
|
| 93 |
}
|
| 94 |
|
| 95 |
k := new(big.Int).SetBytes(scCodeHash)
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
// this code gets actual smart contract code from sc code storage
|
| 98 |
scCode, err := tree.getProgram(ctx, scalarToh4(k))
|
|
@@ -1,86 +0,0 @@
|
|
| 1 |
-
package merkletree
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
"testing"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/EmitLog2"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/test/testutils"
|
| 11 |
-
"github.com/ethereum/go-ethereum/common"
|
| 12 |
-
"github.com/google/uuid"
|
| 13 |
-
"github.com/stretchr/testify/require"
|
| 14 |
-
)
|
| 15 |
-
|
| 16 |
-
func TestGetCode(t *testing.T) {
|
| 17 |
-
ctx := context.Background()
|
| 18 |
-
zkProverURI := testutils.GetEnv("ZKPROVER_URI", "localhost")
|
| 19 |
-
|
| 20 |
-
cfg := Config{URI: fmt.Sprintf("%s:50061", zkProverURI)}
|
| 21 |
-
c, _, _ := NewMTDBServiceClient(ctx, cfg)
|
| 22 |
-
sTree := NewStateTree(c)
|
| 23 |
-
|
| 24 |
-
type testCase struct {
|
| 25 |
-
name string
|
| 26 |
-
addr common.Address
|
| 27 |
-
root []byte
|
| 28 |
-
expectedResult []byte
|
| 29 |
-
expectedError error
|
| 30 |
-
setup func(*testing.T, *testCase, *StateTree)
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
testCases := []testCase{
|
| 34 |
-
{
|
| 35 |
-
name: "get existent code successfully",
|
| 36 |
-
addr: common.HexToAddress("0x1"),
|
| 37 |
-
root: common.HexToHash("0x0").Bytes(),
|
| 38 |
-
expectedResult: hex.DecodeBig(EmitLog2.EmitLog2Bin).Bytes(),
|
| 39 |
-
expectedError: nil,
|
| 40 |
-
setup: func(t *testing.T, tc *testCase, sTree *StateTree) {
|
| 41 |
-
txID := uuid.NewString()
|
| 42 |
-
|
| 43 |
-
err := sTree.StartBlock(ctx, common.Hash(tc.root), txID)
|
| 44 |
-
require.NoError(t, err)
|
| 45 |
-
|
| 46 |
-
newRoot, _, err := sTree.SetCode(ctx, tc.addr, tc.expectedResult, tc.root, txID)
|
| 47 |
-
require.NoError(t, err)
|
| 48 |
-
tc.root = newRoot
|
| 49 |
-
|
| 50 |
-
err = sTree.FinishBlock(ctx, common.Hash(tc.root), txID)
|
| 51 |
-
require.NoError(t, err)
|
| 52 |
-
|
| 53 |
-
err = sTree.Flush(ctx, common.Hash(newRoot), txID)
|
| 54 |
-
require.NoError(t, err)
|
| 55 |
-
},
|
| 56 |
-
},
|
| 57 |
-
{
|
| 58 |
-
name: "get non-existent code successfully",
|
| 59 |
-
addr: common.HexToAddress("0x2"),
|
| 60 |
-
root: common.HexToHash("0x0").Bytes(),
|
| 61 |
-
expectedResult: []byte{},
|
| 62 |
-
expectedError: nil,
|
| 63 |
-
setup: func(t *testing.T, tc *testCase, sTree *StateTree) {
|
| 64 |
-
},
|
| 65 |
-
},
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
for _, tc := range testCases {
|
| 69 |
-
t.Run(tc.name, func(t *testing.T) {
|
| 70 |
-
tc := tc
|
| 71 |
-
tc.setup(t, &tc, sTree)
|
| 72 |
-
|
| 73 |
-
result, err := sTree.GetCode(ctx, tc.addr, tc.root)
|
| 74 |
-
require.NoError(t, err)
|
| 75 |
-
|
| 76 |
-
if tc.expectedResult != nil || result != nil {
|
| 77 |
-
require.Equal(t, len(tc.expectedResult), len(result))
|
| 78 |
-
require.ElementsMatch(t, tc.expectedResult, result)
|
| 79 |
-
}
|
| 80 |
-
|
| 81 |
-
if tc.expectedError != nil || err != nil {
|
| 82 |
-
require.Equal(t, tc.expectedError, err)
|
| 83 |
-
}
|
| 84 |
-
})
|
| 85 |
-
}
|
| 86 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2,21 +2,12 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
-
"errors"
|
| 6 |
"math/big"
|
| 7 |
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 10 |
)
|
| 11 |
|
| 12 |
-
var (
|
| 13 |
-
// ErrEffectiveGasPriceEmpty happens when the effectiveGasPrice or gasPrice is nil or zero
|
| 14 |
-
ErrEffectiveGasPriceEmpty = errors.New("effectiveGasPrice or gasPrice cannot be nil or zero")
|
| 15 |
-
|
| 16 |
-
// ErrEffectiveGasPriceIsZero happens when the calculated EffectiveGasPrice is zero
|
| 17 |
-
ErrEffectiveGasPriceIsZero = errors.New("effectiveGasPrice cannot be zero")
|
| 18 |
-
)
|
| 19 |
-
|
| 20 |
// EffectiveGasPrice implements the effective gas prices calculations and checks
|
| 21 |
type EffectiveGasPrice struct {
|
| 22 |
cfg EffectiveGasPriceCfg
|
|
@@ -122,33 +113,8 @@
|
|
| 122 |
bfEffectiveGasPrice.Int(effectiveGasPrice)
|
| 123 |
|
| 124 |
if effectiveGasPrice.Cmp(new(big.Int).SetUint64(0)) == 0 {
|
| 125 |
-
return nil, ErrEffectiveGasPriceIsZero
|
| 126 |
}
|
| 127 |
|
| 128 |
return effectiveGasPrice, nil
|
| 129 |
}
|
| 130 |
-
|
| 131 |
-
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 132 |
-
func (e *EffectiveGasPrice) CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 133 |
-
const bits = 256
|
| 134 |
-
var bitsBigInt = big.NewInt(bits)
|
| 135 |
-
|
| 136 |
-
if effectiveGasPrice == nil || gasPrice == nil ||
|
| 137 |
-
gasPrice.Cmp(big.NewInt(0)) == 0 || effectiveGasPrice.Cmp(big.NewInt(0)) == 0 {
|
| 138 |
-
return 0, ErrEffectiveGasPriceEmpty
|
| 139 |
-
}
|
| 140 |
-
|
| 141 |
-
if gasPrice.Cmp(effectiveGasPrice) <= 0 {
|
| 142 |
-
return state.MaxEffectivePercentage, nil
|
| 143 |
-
}
|
| 144 |
-
|
| 145 |
-
// Simulate Ceil with integer division
|
| 146 |
-
b := new(big.Int).Mul(effectiveGasPrice, bitsBigInt)
|
| 147 |
-
b = b.Add(b, gasPrice)
|
| 148 |
-
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 149 |
-
b = b.Div(b, gasPrice)
|
| 150 |
-
// At this point we have a percentage between 1-256, we need to sub 1 to have it between 0-255 (byte)
|
| 151 |
-
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 152 |
-
|
| 153 |
-
return uint8(b.Uint64()), nil
|
| 154 |
-
}
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
|
|
|
| 5 |
"math/big"
|
| 6 |
|
| 7 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
)
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
// EffectiveGasPrice implements the effective gas prices calculations and checks
|
| 12 |
type EffectiveGasPrice struct {
|
| 13 |
cfg EffectiveGasPriceCfg
|
|
|
|
| 113 |
bfEffectiveGasPrice.Int(effectiveGasPrice)
|
| 114 |
|
| 115 |
if effectiveGasPrice.Cmp(new(big.Int).SetUint64(0)) == 0 {
|
| 116 |
+
return nil, state.ErrEffectiveGasPriceIsZero
|
| 117 |
}
|
| 118 |
|
| 119 |
return effectiveGasPrice, nil
|
| 120 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -23,8 +24,6 @@
|
|
| 23 |
)
|
| 24 |
|
| 25 |
func TestCalculateEffectiveGasPricePercentage(t *testing.T) {
|
| 26 |
-
egp := NewEffectiveGasPrice(egpCfg)
|
| 27 |
-
|
| 28 |
testCases := []struct {
|
| 29 |
name string
|
| 30 |
breakEven *big.Int
|
|
@@ -37,14 +36,14 @@
|
|
| 37 |
name: "Nil breakEven or gasPrice",
|
| 38 |
gasPrice: big.NewInt(1),
|
| 39 |
expectedValue: uint8(0),
|
| 40 |
-
err: ErrEffectiveGasPriceEmpty,
|
| 41 |
},
|
| 42 |
{
|
| 43 |
name: "Zero breakEven or gasPrice",
|
| 44 |
breakEven: big.NewInt(1),
|
| 45 |
gasPrice: big.NewInt(0),
|
| 46 |
expectedValue: uint8(0),
|
| 47 |
-
err: ErrEffectiveGasPriceEmpty,
|
| 48 |
},
|
| 49 |
{
|
| 50 |
name: "Both positive, gasPrice less than breakEven",
|
|
@@ -104,7 +103,7 @@
|
|
| 104 |
|
| 105 |
for _, tc := range testCases {
|
| 106 |
t.Run(tc.name, func(t *testing.T) {
|
| 107 |
-
actual, err :=
|
| 108 |
assert.Equal(t, tc.err, err)
|
| 109 |
if actual != 0 {
|
| 110 |
assert.Equal(t, tc.expectedValue, actual)
|
|
|
|
| 24 |
)
|
| 25 |
|
| 26 |
func TestCalculateEffectiveGasPricePercentage(t *testing.T) {
|
|
|
|
|
|
|
| 27 |
testCases := []struct {
|
| 28 |
name string
|
| 29 |
breakEven *big.Int
|
|
|
|
| 36 |
name: "Nil breakEven or gasPrice",
|
| 37 |
gasPrice: big.NewInt(1),
|
| 38 |
expectedValue: uint8(0),
|
| 39 |
+
err: state.ErrEffectiveGasPriceEmpty,
|
| 40 |
},
|
| 41 |
{
|
| 42 |
name: "Zero breakEven or gasPrice",
|
| 43 |
breakEven: big.NewInt(1),
|
| 44 |
gasPrice: big.NewInt(0),
|
| 45 |
expectedValue: uint8(0),
|
| 46 |
+
err: state.ErrEffectiveGasPriceEmpty,
|
| 47 |
},
|
| 48 |
{
|
| 49 |
name: "Both positive, gasPrice less than breakEven",
|
|
|
|
| 103 |
|
| 104 |
for _, tc := range testCases {
|
| 105 |
t.Run(tc.name, func(t *testing.T) {
|
| 106 |
+
actual, err := state.CalculateEffectiveGasPricePercentage(tc.gasPrice, tc.breakEven)
|
| 107 |
assert.Equal(t, tc.err, err)
|
| 108 |
if actual != 0 {
|
| 109 |
assert.Equal(t, tc.expectedValue, actual)
|
|
@@ -76,4 +76,13 @@
|
|
| 76 |
|
| 77 |
// ErrZeroL1GasPrice is returned if the L1 gas price is 0.
|
| 78 |
ErrZeroL1GasPrice = errors.New("L1 gas price 0")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
)
|
|
|
|
| 76 |
|
| 77 |
// ErrZeroL1GasPrice is returned if the L1 gas price is 0.
|
| 78 |
ErrZeroL1GasPrice = errors.New("L1 gas price 0")
|
| 79 |
+
|
| 80 |
+
// ErrSenderDisallowedSendTx is returned when transactions by sender are is disallowed by policy
|
| 81 |
+
ErrSenderDisallowedSendTx = errors.New("sender disallowed send_tx by policy")
|
| 82 |
+
|
| 83 |
+
// ErrContractDisallowedSendTx is returned when transactions to contract are is disallowed by policy
|
| 84 |
+
ErrContractDisallowedSendTx = errors.New("contract disallowed send_tx by policy")
|
| 85 |
+
|
| 86 |
+
// ErrSenderDisallowedDeploy is returned when deploy transactions are disallowed by policy
|
| 87 |
+
ErrSenderDisallowedDeploy = errors.New("sender disallowed deploy by policy")
|
| 88 |
)
|
|
@@ -38,6 +38,7 @@
|
|
| 38 |
MarkWIPTxsAsPending(ctx context.Context) error
|
| 39 |
GetAllAddressesBlocked(ctx context.Context) ([]common.Address, error)
|
| 40 |
MinL2GasPriceSince(ctx context.Context, timestamp time.Time) (uint64, error)
|
|
|
|
| 41 |
GetEarliestProcessedTx(ctx context.Context) (common.Hash, error)
|
| 42 |
}
|
| 43 |
|
|
@@ -48,3 +49,12 @@
|
|
| 48 |
GetTransactionByHash(ctx context.Context, transactionHash common.Hash, dbTx pgx.Tx) (*types.Transaction, error)
|
| 49 |
PreProcessTransaction(ctx context.Context, tx *types.Transaction, dbTx pgx.Tx) (*state.ProcessBatchResponse, error)
|
| 50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
MarkWIPTxsAsPending(ctx context.Context) error
|
| 39 |
GetAllAddressesBlocked(ctx context.Context) ([]common.Address, error)
|
| 40 |
MinL2GasPriceSince(ctx context.Context, timestamp time.Time) (uint64, error)
|
| 41 |
+
policy
|
| 42 |
GetEarliestProcessedTx(ctx context.Context) (common.Hash, error)
|
| 43 |
}
|
| 44 |
|
|
|
|
| 49 |
GetTransactionByHash(ctx context.Context, transactionHash common.Hash, dbTx pgx.Tx) (*types.Transaction, error)
|
| 50 |
PreProcessTransaction(ctx context.Context, tx *types.Transaction, dbTx pgx.Tx) (*state.ProcessBatchResponse, error)
|
| 51 |
}
|
| 52 |
+
type policy interface {
|
| 53 |
+
CheckPolicy(ctx context.Context, policy PolicyName, address common.Address) (bool, error)
|
| 54 |
+
AddAddressesToPolicy(ctx context.Context, policy PolicyName, addresses []common.Address) error
|
| 55 |
+
RemoveAddressesFromPolicy(ctx context.Context, policy PolicyName, addresses []common.Address) error
|
| 56 |
+
ClearPolicy(ctx context.Context, policy PolicyName) error
|
| 57 |
+
DescribePolicies(ctx context.Context) ([]Policy, error)
|
| 58 |
+
DescribePolicy(ctx context.Context, name PolicyName) (Policy, error)
|
| 59 |
+
ListAcl(ctx context.Context, policy PolicyName, query []common.Address) ([]common.Address, error)
|
| 60 |
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package pgpoolstorage
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"errors"
|
| 6 |
+
"fmt"
|
| 7 |
+
"strings"
|
| 8 |
+
|
| 9 |
+
"github.com/0xPolygonHermez/zkevm-node/pool"
|
| 10 |
+
"github.com/ethereum/go-ethereum/common"
|
| 11 |
+
"github.com/jackc/pgx/v4"
|
| 12 |
+
)
|
| 13 |
+
|
| 14 |
+
// CheckPolicy returns the rule for the named policy and address. If the address is associated with the policy, the rule
|
| 15 |
+
// will be the setting for the policy. If the address is no associated with the policy, the rule will be the opposite of
|
| 16 |
+
// the policy setting.
|
| 17 |
+
func (p *PostgresPoolStorage) CheckPolicy(ctx context.Context, policy pool.PolicyName, address common.Address) (bool, error) {
|
| 18 |
+
sql := `SELECT
|
| 19 |
+
CASE WHEN a.address is null THEN
|
| 20 |
+
NOT p.allow
|
| 21 |
+
ELSE
|
| 22 |
+
p.allow
|
| 23 |
+
END
|
| 24 |
+
FROM pool.policy p
|
| 25 |
+
LEFT JOIN pool.acl a
|
| 26 |
+
ON p.name = a.policy
|
| 27 |
+
AND a.address = $1
|
| 28 |
+
WHERE p.name = $2`
|
| 29 |
+
|
| 30 |
+
rows, err := p.db.Query(ctx, sql, address.Hex(), policy)
|
| 31 |
+
|
| 32 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 33 |
+
return false, pool.ErrNotFound
|
| 34 |
+
} else if err != nil {
|
| 35 |
+
return false, err
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
defer rows.Close()
|
| 39 |
+
if !rows.Next() { // should always be a row if the policy exists
|
| 40 |
+
return false, nil
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
var allow bool
|
| 44 |
+
err = rows.Scan(&allow)
|
| 45 |
+
if err != nil {
|
| 46 |
+
return false, err
|
| 47 |
+
}
|
| 48 |
+
return allow, nil
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// UpdatePolicy sets the allow/deny rule for the named policy
|
| 52 |
+
func (p *PostgresPoolStorage) UpdatePolicy(ctx context.Context, policy pool.PolicyName, allow bool) error {
|
| 53 |
+
sql := "UPDATE pool.policy SET allow = $1 WHERE name = $2"
|
| 54 |
+
_, err := p.db.Exec(ctx, sql, allow, string(policy))
|
| 55 |
+
if err != nil {
|
| 56 |
+
return err
|
| 57 |
+
}
|
| 58 |
+
return nil
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
// AddAddressesToPolicy adds addresses to the named policy
|
| 62 |
+
func (p *PostgresPoolStorage) AddAddressesToPolicy(ctx context.Context, policy pool.PolicyName, addresses []common.Address) error {
|
| 63 |
+
sql := "INSERT INTO pool.acl (policy, address) VALUES ($1, $2) ON CONFLICT DO NOTHING"
|
| 64 |
+
tx, err := p.db.Begin(ctx)
|
| 65 |
+
if err != nil {
|
| 66 |
+
return err
|
| 67 |
+
}
|
| 68 |
+
defer func(tx pgx.Tx, ctx context.Context) {
|
| 69 |
+
_ = tx.Rollback(ctx)
|
| 70 |
+
}(tx, ctx)
|
| 71 |
+
|
| 72 |
+
for _, a := range addresses {
|
| 73 |
+
_, err = tx.Exec(ctx, sql, policy, a.Hex())
|
| 74 |
+
if err != nil {
|
| 75 |
+
return err
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
err = tx.Commit(ctx)
|
| 79 |
+
if err != nil {
|
| 80 |
+
return nil
|
| 81 |
+
}
|
| 82 |
+
return nil
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
// RemoveAddressesFromPolicy removes addresses from the named policy
|
| 86 |
+
func (p *PostgresPoolStorage) RemoveAddressesFromPolicy(ctx context.Context, policy pool.PolicyName, addresses []common.Address) error {
|
| 87 |
+
sql := "DELETE FROM pool.acl WHERE policy = $1 AND address = $2"
|
| 88 |
+
tx, err := p.db.Begin(ctx)
|
| 89 |
+
if err != nil {
|
| 90 |
+
return err
|
| 91 |
+
}
|
| 92 |
+
defer func(tx pgx.Tx, ctx context.Context) {
|
| 93 |
+
_ = tx.Rollback(ctx)
|
| 94 |
+
}(tx, ctx)
|
| 95 |
+
|
| 96 |
+
for _, a := range addresses {
|
| 97 |
+
_, err = tx.Exec(ctx, sql, policy, a.Hex())
|
| 98 |
+
if err != nil {
|
| 99 |
+
return err
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
err = tx.Commit(ctx)
|
| 103 |
+
if err != nil {
|
| 104 |
+
return err
|
| 105 |
+
}
|
| 106 |
+
return nil
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
// ClearPolicy removes _all_ addresses from the named policy
|
| 110 |
+
func (p *PostgresPoolStorage) ClearPolicy(ctx context.Context, policy pool.PolicyName) error {
|
| 111 |
+
sql := "DELETE FROM pool.acl WHERE policy = $1"
|
| 112 |
+
_, err := p.db.Exec(ctx, sql, policy)
|
| 113 |
+
if err != nil {
|
| 114 |
+
return err
|
| 115 |
+
}
|
| 116 |
+
return nil
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
// DescribePolicies return all the policies
|
| 120 |
+
func (p *PostgresPoolStorage) DescribePolicies(ctx context.Context) ([]pool.Policy, error) {
|
| 121 |
+
sql := "SELECT name, allow FROM pool.policy"
|
| 122 |
+
rows, err := p.db.Query(ctx, sql)
|
| 123 |
+
if err != nil {
|
| 124 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 125 |
+
return nil, nil
|
| 126 |
+
} else {
|
| 127 |
+
return nil, err
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
defer rows.Close()
|
| 131 |
+
|
| 132 |
+
var list []pool.Policy
|
| 133 |
+
for rows.Next() {
|
| 134 |
+
var name string
|
| 135 |
+
var allow bool
|
| 136 |
+
err = rows.Scan(&name, &allow)
|
| 137 |
+
if err != nil {
|
| 138 |
+
return nil, err
|
| 139 |
+
}
|
| 140 |
+
if pool.IsPolicy(name) { // skip unknown
|
| 141 |
+
p := pool.Policy{
|
| 142 |
+
Name: pool.PolicyName(name),
|
| 143 |
+
Allow: allow,
|
| 144 |
+
}
|
| 145 |
+
list = append(list, p)
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
return list, nil
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
// DescribePolicy returns the named policy
|
| 152 |
+
func (p *PostgresPoolStorage) DescribePolicy(ctx context.Context, name pool.PolicyName) (pool.Policy, error) {
|
| 153 |
+
sql := "SELECT name, allow FROM pool.policy WHERE name = $1 LIMIT 1"
|
| 154 |
+
row := p.db.QueryRow(ctx, sql, name)
|
| 155 |
+
var (
|
| 156 |
+
pName string
|
| 157 |
+
allow bool
|
| 158 |
+
)
|
| 159 |
+
err := row.Scan(&pName, &allow)
|
| 160 |
+
if err != nil {
|
| 161 |
+
return pool.Policy{}, err
|
| 162 |
+
}
|
| 163 |
+
return pool.Policy{
|
| 164 |
+
Name: pool.PolicyName(pName),
|
| 165 |
+
Allow: allow,
|
| 166 |
+
}, nil
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
// ListAcl returns a list of the addresses associated with the policy
|
| 170 |
+
func (p *PostgresPoolStorage) ListAcl(
|
| 171 |
+
ctx context.Context, policy pool.PolicyName, query []common.Address) ([]common.Address, error) {
|
| 172 |
+
sql := "SELECT address FROM pool.acl WHERE policy = $1"
|
| 173 |
+
|
| 174 |
+
if len(query) > 0 {
|
| 175 |
+
var addrs []string
|
| 176 |
+
for _, a := range query {
|
| 177 |
+
addrs = append(addrs, a.Hex())
|
| 178 |
+
}
|
| 179 |
+
sql = sql + fmt.Sprintf(" IN (%v)", strings.Join(addrs, ","))
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
rows, err := p.db.Query(ctx, sql, string(policy))
|
| 183 |
+
if err != nil {
|
| 184 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 185 |
+
return nil, nil
|
| 186 |
+
} else {
|
| 187 |
+
return nil, err
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
defer rows.Close()
|
| 191 |
+
|
| 192 |
+
var addresses []common.Address
|
| 193 |
+
for rows.Next() {
|
| 194 |
+
var addr string
|
| 195 |
+
err = rows.Scan(&addr)
|
| 196 |
+
if err != nil {
|
| 197 |
+
return nil, err
|
| 198 |
+
}
|
| 199 |
+
addresses = append(addresses, common.HexToAddress(addr))
|
| 200 |
+
}
|
| 201 |
+
return addresses, nil
|
| 202 |
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package pool
|
| 2 |
+
|
| 3 |
+
import "github.com/ethereum/go-ethereum/common"
|
| 4 |
+
|
| 5 |
+
// PolicyName is a named policy
|
| 6 |
+
type PolicyName string
|
| 7 |
+
|
| 8 |
+
const (
|
| 9 |
+
// SendTx is the name of the policy that governs that an address may send transactions to pool
|
| 10 |
+
SendTx PolicyName = "send_tx"
|
| 11 |
+
// Deploy is the name of the policy that governs that an address may deploy a contract
|
| 12 |
+
Deploy PolicyName = "deploy"
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
// Policy describes state of a named policy
|
| 16 |
+
type Policy struct {
|
| 17 |
+
Name PolicyName
|
| 18 |
+
Allow bool
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
// Desc returns the string representation of a policy rule
|
| 22 |
+
func (p *Policy) Desc() string {
|
| 23 |
+
if p.Allow {
|
| 24 |
+
return "allow"
|
| 25 |
+
}
|
| 26 |
+
return "deny"
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// Acl describes exception to a named Policy by address
|
| 30 |
+
type Acl struct {
|
| 31 |
+
PolicyName PolicyName
|
| 32 |
+
Address common.Address
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// IsPolicy tests if a string represents a known named Policy
|
| 36 |
+
func IsPolicy(name string) bool {
|
| 37 |
+
for _, p := range []PolicyName{SendTx, Deploy} {
|
| 38 |
+
if name == string(p) {
|
| 39 |
+
return true
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
return false
|
| 43 |
+
}
|
|
@@ -93,6 +93,13 @@
|
|
| 93 |
time.Sleep(cfg.IntervalToRefreshGasPrices.Duration)
|
| 94 |
}
|
| 95 |
}(&cfg, p)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
return p
|
| 98 |
}
|
|
@@ -239,7 +246,6 @@
|
|
| 239 |
}
|
| 240 |
|
| 241 |
poolTx := NewTransaction(tx, ip, isWIP)
|
| 242 |
-
poolTx.GasUsed = preExecutionResponse.txResponse.GasUsed
|
| 243 |
poolTx.ZKCounters = preExecutionResponse.usedZKCounters
|
| 244 |
poolTx.ReservedZKCounters = preExecutionResponse.reservedZKCounters
|
| 245 |
|
|
@@ -687,7 +693,7 @@
|
|
| 687 |
|
| 688 |
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 689 |
func (p *Pool) CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 690 |
-
return
|
| 691 |
}
|
| 692 |
|
| 693 |
// EffectiveGasPriceEnabled returns if effective gas price calculation is enabled or not
|
|
@@ -729,3 +735,8 @@
|
|
| 729 |
}
|
| 730 |
return gas, nil
|
| 731 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
time.Sleep(cfg.IntervalToRefreshGasPrices.Duration)
|
| 94 |
}
|
| 95 |
}(&cfg, p)
|
| 96 |
+
p.refreshBlockedAddresses()
|
| 97 |
+
go func(cfg *Config, p *Pool) {
|
| 98 |
+
for {
|
| 99 |
+
time.Sleep(cfg.IntervalToRefreshBlockedAddresses.Duration)
|
| 100 |
+
p.refreshBlockedAddresses()
|
| 101 |
+
}
|
| 102 |
+
}(&cfg, p)
|
| 103 |
|
| 104 |
return p
|
| 105 |
}
|
|
|
|
| 246 |
}
|
| 247 |
|
| 248 |
poolTx := NewTransaction(tx, ip, isWIP)
|
|
|
|
| 249 |
poolTx.ZKCounters = preExecutionResponse.usedZKCounters
|
| 250 |
poolTx.ReservedZKCounters = preExecutionResponse.reservedZKCounters
|
| 251 |
|
|
|
|
| 693 |
|
| 694 |
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 695 |
func (p *Pool) CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 696 |
+
return state.CalculateEffectiveGasPricePercentage(gasPrice, effectiveGasPrice)
|
| 697 |
}
|
| 698 |
|
| 699 |
// EffectiveGasPriceEnabled returns if effective gas price calculation is enabled or not
|
|
|
|
| 735 |
}
|
| 736 |
return gas, nil
|
| 737 |
}
|
| 738 |
+
|
| 739 |
+
// CheckPolicy checks if an address is allowed by policy name
|
| 740 |
+
func (p *Pool) CheckPolicy(ctx context.Context, policy PolicyName, address common.Address) (bool, error) {
|
| 741 |
+
return p.storage.CheckPolicy(ctx, policy, address)
|
| 742 |
+
}
|
|
@@ -1114,7 +1114,7 @@
|
|
| 1114 |
stateDBClient, _, _ := merkletree.NewMTDBServiceClient(ctx, mtDBServerConfig)
|
| 1115 |
stateTree := merkletree.NewStateTree(stateDBClient)
|
| 1116 |
|
| 1117 |
-
st := state.NewState(stCfg, stateDb, executorClient, stateTree, eventLog, nil
|
| 1118 |
return st
|
| 1119 |
}
|
| 1120 |
|
|
@@ -2032,3 +2032,69 @@
|
|
| 2032 |
require.NoError(t, err)
|
| 2033 |
return signedTx
|
| 2034 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1114 |
stateDBClient, _, _ := merkletree.NewMTDBServiceClient(ctx, mtDBServerConfig)
|
| 1115 |
stateTree := merkletree.NewStateTree(stateDBClient)
|
| 1116 |
|
| 1117 |
+
st := state.NewState(stCfg, stateDb, executorClient, stateTree, eventLog, nil)
|
| 1118 |
return st
|
| 1119 |
}
|
| 1120 |
|
|
|
|
| 2032 |
require.NoError(t, err)
|
| 2033 |
return signedTx
|
| 2034 |
}
|
| 2035 |
+
|
| 2036 |
+
func Test_PolicyAcl(t *testing.T) {
|
| 2037 |
+
initOrResetDB(t)
|
| 2038 |
+
|
| 2039 |
+
poolSqlDB, err := db.NewSQLDB(poolDBCfg)
|
| 2040 |
+
require.NoError(t, err)
|
| 2041 |
+
defer poolSqlDB.Close() //nolint:gosec,errcheck
|
| 2042 |
+
|
| 2043 |
+
ctx := context.Background()
|
| 2044 |
+
s, err := pgpoolstorage.NewPostgresPoolStorage(poolDBCfg)
|
| 2045 |
+
require.NoError(t, err)
|
| 2046 |
+
|
| 2047 |
+
p := pool.NewPool(cfg, bc, s, nil, uint64(1), nil)
|
| 2048 |
+
|
| 2049 |
+
randAddr := func() common.Address {
|
| 2050 |
+
buf := make([]byte, 20)
|
| 2051 |
+
_, err = rand.Read(buf)
|
| 2052 |
+
require.NoError(t, err)
|
| 2053 |
+
return common.BytesToAddress(buf)
|
| 2054 |
+
}
|
| 2055 |
+
|
| 2056 |
+
// Policies start out as deny lists, since there are no addresses on the
|
| 2057 |
+
// lists, random addresses will always be allowed
|
| 2058 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2059 |
+
allow, err := p.CheckPolicy(ctx, policy, randAddr())
|
| 2060 |
+
require.NoError(t, err)
|
| 2061 |
+
require.True(t, allow)
|
| 2062 |
+
}
|
| 2063 |
+
|
| 2064 |
+
addr := randAddr()
|
| 2065 |
+
|
| 2066 |
+
// put addr on lists
|
| 2067 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2068 |
+
ctag, err := poolSqlDB.Exec(ctx, "INSERT INTO pool.acl (policy, address) VALUES ($1,$2)", policy, addr.Hex())
|
| 2069 |
+
require.NoError(t, err)
|
| 2070 |
+
require.Equal(t, int64(1), ctag.RowsAffected())
|
| 2071 |
+
}
|
| 2072 |
+
|
| 2073 |
+
// addr should not be denied by policy
|
| 2074 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2075 |
+
allow, err := p.CheckPolicy(ctx, policy, addr)
|
| 2076 |
+
require.NoError(t, err)
|
| 2077 |
+
require.False(t, allow)
|
| 2078 |
+
}
|
| 2079 |
+
|
| 2080 |
+
// change policies to allow by acl
|
| 2081 |
+
ctag, err := poolSqlDB.Exec(ctx, "UPDATE pool.policy SET allow = true")
|
| 2082 |
+
require.NoError(t, err)
|
| 2083 |
+
require.Equal(t, int64(2), ctag.RowsAffected())
|
| 2084 |
+
|
| 2085 |
+
// addr is now allowed
|
| 2086 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2087 |
+
allow, err := p.CheckPolicy(ctx, policy, addr)
|
| 2088 |
+
require.NoError(t, err)
|
| 2089 |
+
require.True(t, allow)
|
| 2090 |
+
}
|
| 2091 |
+
|
| 2092 |
+
// random addrs are now denied
|
| 2093 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2094 |
+
for _, a := range []common.Address{randAddr(), randAddr()} {
|
| 2095 |
+
allow, err := s.CheckPolicy(ctx, policy, a)
|
| 2096 |
+
require.NoError(t, err)
|
| 2097 |
+
require.False(t, allow)
|
| 2098 |
+
}
|
| 2099 |
+
}
|
| 2100 |
+
}
|
|
@@ -10,9 +10,6 @@
|
|
| 10 |
/// Processes a batch
|
| 11 |
rpc ProcessBatch(ProcessBatchRequest) returns (ProcessBatchResponse) {}
|
| 12 |
rpc ProcessBatchV2(ProcessBatchRequestV2) returns (ProcessBatchResponseV2) {}
|
| 13 |
-
rpc ProcessBatchV3(ProcessBatchRequestV3) returns (ProcessBatchResponseV3) {}
|
| 14 |
-
rpc ProcessBlobInnerV3(ProcessBlobInnerRequestV3) returns (ProcessBlobInnerResponseV3) {}
|
| 15 |
-
rpc ProcessStatelessBatchV2(ProcessStatelessBatchRequestV2) returns (ProcessBatchResponseV2) {}
|
| 16 |
rpc GetFlushStatus (google.protobuf.Empty) returns (GetFlushStatusResponse) {}
|
| 17 |
}
|
| 18 |
|
|
@@ -295,27 +292,7 @@
|
|
| 295 |
// prior to executing the call.
|
| 296 |
map<string, OverrideAccountV2> state_override = 23;
|
| 297 |
DebugV2 debug = 24;
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
message ProcessStatelessBatchRequestV2 {
|
| 301 |
-
// Batch data
|
| 302 |
-
bytes witness = 1; // SMT partial tree, SCs, (indirectly) old state root
|
| 303 |
-
bytes data_stream = 2; // txs, old batch num, chain id, fork id, effective gas price, block header, index of L1 info tree (global exit root, min timestamp, ...)
|
| 304 |
-
|
| 305 |
-
string coinbase = 3; // sequencer address
|
| 306 |
-
bytes old_acc_input_hash = 4; // 0 for executor, required for the prover
|
| 307 |
-
|
| 308 |
-
// Used by injected/first batches (do not use it for regular batches)
|
| 309 |
-
bytes l1_info_root = 5; // 0 for executor, required for the prover
|
| 310 |
-
uint64 timestamp_limit = 6; // if 0, replace by now + 10 min internally
|
| 311 |
-
bytes forced_blockhash_l1 = 7; // we need it, 0 in regular batches, hash in forced batches, also used in injected/first batches, 0 by now
|
| 312 |
-
|
| 313 |
-
// Debug
|
| 314 |
-
string context_id = 8; // batch ID to be shown in the executor traces, for your convenience: "Erigon_candidate_batch_N"
|
| 315 |
-
TraceConfigV2 trace_config = 9;
|
| 316 |
-
|
| 317 |
-
// Mapping to provide minTimestamp for each l1InfoTreeIndex in a batch
|
| 318 |
-
map<uint64, uint64> l1_info_tree_index_min_timestamp = 10;
|
| 319 |
}
|
| 320 |
|
| 321 |
message L1DataV2 {
|
|
@@ -327,7 +304,7 @@
|
|
| 327 |
|
| 328 |
message DebugV2 {
|
| 329 |
uint64 gas_limit = 1;
|
| 330 |
-
bytes new_state_root = 2;
|
| 331 |
bytes new_acc_input_hash = 3;
|
| 332 |
bytes new_local_exit_root = 4;
|
| 333 |
uint64 new_batch_num = 5;
|
|
@@ -366,13 +343,6 @@
|
|
| 366 |
uint32 cnt_reserve_binaries = 30;
|
| 367 |
uint32 cnt_reserve_steps = 31;
|
| 368 |
uint32 cnt_reserve_sha256_hashes = 32;
|
| 369 |
-
bytes old_state_root = 33;
|
| 370 |
-
ResponseDebug debug = 34;
|
| 371 |
-
}
|
| 372 |
-
|
| 373 |
-
message ResponseDebug {
|
| 374 |
-
string error_log = 1;
|
| 375 |
-
string version = 2;
|
| 376 |
}
|
| 377 |
|
| 378 |
// Trace configuration request params
|
|
@@ -413,12 +383,6 @@
|
|
| 413 |
string nonce = 1;
|
| 414 |
// If balance="" then it has not been set; if set, string is in decimal (base 10)
|
| 415 |
string balance = 2;
|
| 416 |
-
// If sc_code="" then it has not been set; if set, string is in hexa (base 16)
|
| 417 |
-
string sc_code = 3;
|
| 418 |
-
// Both sc_storage first (key) and second (value) map elements are set in hexa (base 16)
|
| 419 |
-
map<string, string> sc_storage = 4;
|
| 420 |
-
// If sc_length="" then it has not been set; if set, string is in decimal (base 10)
|
| 421 |
-
string sc_length = 5;
|
| 422 |
}
|
| 423 |
|
| 424 |
message FullTraceV2 {
|
|
@@ -672,8 +636,6 @@
|
|
| 672 |
ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_LIMIT_TIMESTAMP = 33;
|
| 673 |
// ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP indicates that the change l2 block transaction has trigger an error during while executing
|
| 674 |
ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP = 34;
|
| 675 |
-
// ROM_ERROR_INVALID_L1_INFO_TREE_INDEX indicates that the l1 info tree index added is not valid since its value is 0
|
| 676 |
-
ROM_ERROR_INVALID_L1_INFO_TREE_INDEX = 35;
|
| 677 |
}
|
| 678 |
|
| 679 |
enum ExecutorError {
|
|
@@ -913,210 +875,4 @@
|
|
| 913 |
EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE = 116;
|
| 914 |
// EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR indicates that a TX has an invalid status-error combination
|
| 915 |
EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR = 117;
|
| 916 |
-
// EXECUTOR_ERROR_INVALID_PREVIOUS_L1_INFO_TREE_ROOT indicates that the input parameter previous_l1_info_tree_root is invalid
|
| 917 |
-
EXECUTOR_ERROR_INVALID_PREVIOUS_L1_INFO_TREE_ROOT = 118;
|
| 918 |
-
// EXECUTOR_ERROR_INVALID_FORCED_HASH_DATA indicates that the input parameter forced_hash_data is invalid
|
| 919 |
-
EXECUTOR_ERROR_INVALID_FORCED_HASH_DATA = 119;
|
| 920 |
-
// EXECUTOR_ERROR_INVALID_FORCED_DATA_GLOBAL_EXIT_ROOT indicates that the input parameter forced_data.global_exit_root is invalid
|
| 921 |
-
EXECUTOR_ERROR_INVALID_FORCED_DATA_GLOBAL_EXIT_ROOT = 120;
|
| 922 |
-
// EXECUTOR_ERROR_INVALID_FORCED_DATA_BLOCK_HASH_L1 indicates that the input parameter forced_data.block_hash_l1 is invalid
|
| 923 |
-
EXECUTOR_ERROR_INVALID_FORCED_DATA_BLOCK_HASH_L1 = 121;
|
| 924 |
-
// EXECUTOR_ERROR_INVALID_L1_DATA_V3_INITIAL_HISTORIC_ROOT indicates that the input parameter L1 Data initiali_historic_root is invalid
|
| 925 |
-
EXECUTOR_ERROR_INVALID_L1_DATA_V3_INITIAL_HISTORIC_ROOT = 122;
|
| 926 |
-
// EXECUTOR_ERROR_INVALID_OLD_BLOB_STATE_ROOT indicates that the input parameter old_blob_state_root is invalid
|
| 927 |
-
EXECUTOR_ERROR_INVALID_OLD_BLOB_STATE_ROOT = 123;
|
| 928 |
-
// EXECUTOR_ERROR_INVALID_OLD_BLOB_ACC_INPUT_HASH indicates that the input parameter old_blob_acc_input_hash is invalid
|
| 929 |
-
EXECUTOR_ERROR_INVALID_OLD_BLOB_ACC_INPUT_HASH = 124;
|
| 930 |
-
// EXECUTOR_ERROR_INVALID_LAST_L1_INFO_TREE_ROOT indicates that the input parameter last_l1_info_tree_root is invalid
|
| 931 |
-
EXECUTOR_ERROR_INVALID_LAST_L1_INFO_TREE_ROOT = 125;
|
| 932 |
-
// EXECUTOR_ERROR_INVALID_NEW_BLOB_STATE_ROOT indicates that the input parameter new_blob_state_root is invalid
|
| 933 |
-
EXECUTOR_ERROR_INVALID_NEW_BLOB_STATE_ROOT = 126;
|
| 934 |
-
// EXECUTOR_ERROR_INVALID_NEW_BLOB_ACC_INPUT_HASH indicates that the input parameter new_blob_acc_input_hash is invalid
|
| 935 |
-
EXECUTOR_ERROR_INVALID_NEW_BLOB_ACC_INPUT_HASH = 127;
|
| 936 |
-
// EXECUTOR_ERROR_INVALID_BLOB_DATA indicates that the input parameter blob_data is invalid (too long)
|
| 937 |
-
EXECUTOR_ERROR_INVALID_BLOB_DATA = 128;
|
| 938 |
-
// EXECUTOR_ERROR_INVALID_ZK_GAS_LIMIT indicates that the input parameter zk_gas_limit is invalid
|
| 939 |
-
EXECUTOR_ERROR_INVALID_ZK_GAS_LIMIT = 129;
|
| 940 |
-
// EXECUTOR_ERROR_INVALID_POINT_Z indicates that the input parameter point_z is invalid
|
| 941 |
-
EXECUTOR_ERROR_INVALID_POINT_Z = 130;
|
| 942 |
-
// EXECUTOR_ERROR_INVALID_POINT_Y indicates that the input parameter point_y is invalid
|
| 943 |
-
EXECUTOR_ERROR_INVALID_POINT_Y = 131;
|
| 944 |
-
// EXECUTOR_ERROR_SM_MAIN_POINT_Z_MISMATCH indicates that the input parameter point_z is different from the one calculated by the executor
|
| 945 |
-
EXECUTOR_ERROR_SM_MAIN_POINT_Z_MISMATCH = 132;
|
| 946 |
-
// EXECUTOR_ERROR_SM_MAIN_BLOB_L2_HASH_DATA_MISMATCH indicates that the input parameter blob L2 data hash is different from the one calculated by the executor
|
| 947 |
-
EXECUTOR_ERROR_SM_MAIN_BLOB_L2_HASH_DATA_MISMATCH = 133;
|
| 948 |
-
// EXECUTOR_ERROR_SM_MAIN_BATCH_HASH_DATA_MISMATCH indicates that the input parameter batch data hash is different from the one calculated by the executor
|
| 949 |
-
EXECUTOR_ERROR_SM_MAIN_BATCH_HASH_DATA_MISMATCH = 134;
|
| 950 |
-
// EXECUTOR_ERROR_SM_MAIN_INVALID_BLOB_TYPE indicates that the input parameter blob type is invalid
|
| 951 |
-
EXECUTOR_ERROR_SM_MAIN_INVALID_BLOB_TYPE = 135;
|
| 952 |
-
// EXECUTOR_ERROR_SM_MAIN_UNRESTORED_SAVED_CONTEXT indicates that at least one saved context was not restored before finishing the execution
|
| 953 |
-
EXECUTOR_ERROR_SM_MAIN_UNRESTORED_SAVED_CONTEXT = 136;
|
| 954 |
-
// EXECUTOR_ERROR_SM_MAIN_INVALID_MEMORY_CTX indicates that the memory context polynomial was assigned an invalid value
|
| 955 |
-
EXECUTOR_ERROR_SM_MAIN_INVALID_MEMORY_CTX = 137;
|
| 956 |
-
// EXECUTOR_ERROR_INVALID_VERSIONED_HASH indicates that the input parameter versioned_hash is invalid
|
| 957 |
-
EXECUTOR_ERROR_INVALID_VERSIONED_HASH = 138;
|
| 958 |
-
// EXECUTOR_ERROR_INVALID_KZG_COMMITMENT indicates that the input parameter kzg_commitment is invalid
|
| 959 |
-
EXECUTOR_ERROR_INVALID_KZG_COMMITMENT = 139;
|
| 960 |
-
// EXECUTOR_ERROR_INVALID_KZG_PROOF indicates that the input parameter kzg_proof is invalid
|
| 961 |
-
EXECUTOR_ERROR_INVALID_KZG_PROOF = 140;
|
| 962 |
-
}
|
| 963 |
-
|
| 964 |
-
////////////////////////////////////////////////
|
| 965 |
-
//////////// START V3 SECTION ////////////////
|
| 966 |
-
////////////////////////////////////////////////
|
| 967 |
-
|
| 968 |
-
message ProcessBatchRequestV3 {
|
| 969 |
-
bytes old_state_root = 1;
|
| 970 |
-
bytes old_acc_input_hash = 2;
|
| 971 |
-
bytes previous_l1_info_tree_root = 3;
|
| 972 |
-
uint32 previous_l1_info_tree_index = 4;
|
| 973 |
-
uint64 chain_id = 5;
|
| 974 |
-
uint64 fork_id = 6;
|
| 975 |
-
bytes batch_l2_data = 7;
|
| 976 |
-
bytes forced_hash_data = 8;
|
| 977 |
-
ForcedData forced_data = 9;
|
| 978 |
-
string coinbase = 10;
|
| 979 |
-
uint32 update_merkle_tree = 11;
|
| 980 |
-
// flag to indicate that counters should not be taken into account
|
| 981 |
-
uint32 no_counters = 12;
|
| 982 |
-
// from is used for unsigned transactions with sender
|
| 983 |
-
string from = 13;
|
| 984 |
-
// flag to skip the restriction to start a batch with a changeL2Block transaction
|
| 985 |
-
uint32 skip_first_change_l2_block = 14;
|
| 986 |
-
// flag to skip writing the block info root in the state
|
| 987 |
-
uint32 skip_write_block_info_root = 15;
|
| 988 |
-
// lInfoTree information
|
| 989 |
-
map<uint32, L1DataV3> l1_info_tree_data = 16;
|
| 990 |
-
// For testing purposes only
|
| 991 |
-
map<string, string> db = 17;
|
| 992 |
-
map<string, string> contracts_bytecode = 18; // For debug/testing purpposes only. Don't fill this on production
|
| 993 |
-
TraceConfigV2 trace_config = 19;
|
| 994 |
-
string context_id = 20;
|
| 995 |
-
uint32 get_keys = 21; // if 1, the keys used to read or write storage values will be returned
|
| 996 |
-
// The state override set is an optional address-to-state mapping,
|
| 997 |
-
// where each entry specifies some state to be ephemerally overridden
|
| 998 |
-
// prior to executing the call.
|
| 999 |
-
map<string, OverrideAccountV2> state_override = 22;
|
| 1000 |
-
DebugV2 debug = 23;
|
| 1001 |
-
}
|
| 1002 |
-
|
| 1003 |
-
message L1DataV3 {
|
| 1004 |
-
bytes global_exit_root = 1;
|
| 1005 |
-
bytes block_hash_l1 = 2;
|
| 1006 |
-
uint64 min_timestamp = 3;
|
| 1007 |
-
repeated bytes smt_proof_previous_index = 4;
|
| 1008 |
-
bytes initial_historic_root = 5;
|
| 1009 |
}
|
| 1010 |
-
|
| 1011 |
-
message ProcessBatchResponseV3 {
|
| 1012 |
-
bytes new_state_root = 1;
|
| 1013 |
-
bytes new_acc_input_hash = 2;
|
| 1014 |
-
bytes new_local_exit_root = 3;
|
| 1015 |
-
uint64 new_last_timestamp = 4;
|
| 1016 |
-
bytes current_l1_info_tree_root = 5;
|
| 1017 |
-
uint32 current_l1_info_tree_index = 6;
|
| 1018 |
-
uint32 cnt_keccak_hashes = 7;
|
| 1019 |
-
uint32 cnt_poseidon_hashes = 8;
|
| 1020 |
-
uint32 cnt_poseidon_paddings = 9;
|
| 1021 |
-
uint32 cnt_mem_aligns = 10;
|
| 1022 |
-
uint32 cnt_arithmetics = 11;
|
| 1023 |
-
uint32 cnt_binaries = 12;
|
| 1024 |
-
uint32 cnt_steps = 13;
|
| 1025 |
-
uint32 cnt_sha256_hashes = 14;
|
| 1026 |
-
repeated ProcessBlockResponseV2 block_responses = 15;
|
| 1027 |
-
ExecutorError error = 16;
|
| 1028 |
-
map<string, InfoReadWriteV2> read_write_addresses = 17;
|
| 1029 |
-
uint64 flush_id = 18;
|
| 1030 |
-
uint64 stored_flush_id = 19;
|
| 1031 |
-
string prover_id = 20;
|
| 1032 |
-
uint64 gas_used = 21;
|
| 1033 |
-
repeated bytes smt_keys = 22;
|
| 1034 |
-
repeated bytes program_keys = 23;
|
| 1035 |
-
uint64 fork_id = 24;
|
| 1036 |
-
uint32 invalid_batch = 25;
|
| 1037 |
-
RomError error_rom = 26;
|
| 1038 |
-
uint32 cnt_reserve_keccak_hashes = 27;
|
| 1039 |
-
uint32 cnt_reserve_poseidon_hashes = 28;
|
| 1040 |
-
uint32 cnt_reserve_poseidon_paddings = 29;
|
| 1041 |
-
uint32 cnt_reserve_mem_aligns = 30;
|
| 1042 |
-
uint32 cnt_reserve_arithmetics = 31;
|
| 1043 |
-
uint32 cnt_reserve_binaries = 32;
|
| 1044 |
-
uint32 cnt_reserve_steps = 33;
|
| 1045 |
-
uint32 cnt_reserve_sha256_hashes = 34;
|
| 1046 |
-
bytes old_state_root = 35;
|
| 1047 |
-
ResponseDebug debug = 36;
|
| 1048 |
-
}
|
| 1049 |
-
|
| 1050 |
-
message ForcedData {
|
| 1051 |
-
bytes global_exit_root = 1;
|
| 1052 |
-
bytes block_hash_l1 = 2;
|
| 1053 |
-
uint64 min_timestamp = 3;
|
| 1054 |
-
}
|
| 1055 |
-
|
| 1056 |
-
message ProcessBlobInnerRequestV3 {
|
| 1057 |
-
// inputs
|
| 1058 |
-
bytes old_blob_state_root = 1;
|
| 1059 |
-
bytes old_blob_acc_input_hash = 2;
|
| 1060 |
-
uint64 old_num_blob = 3;
|
| 1061 |
-
bytes old_state_root = 4;
|
| 1062 |
-
uint64 fork_id = 5;
|
| 1063 |
-
// belong to blobAccInputHash
|
| 1064 |
-
uint32 last_l1_info_tree_index = 6;
|
| 1065 |
-
bytes last_l1_info_tree_root = 7;
|
| 1066 |
-
uint64 timestamp_limit = 8;
|
| 1067 |
-
string coinbase = 9;
|
| 1068 |
-
uint64 zk_gas_limit = 10;
|
| 1069 |
-
uint32 blob_type = 11;
|
| 1070 |
-
bytes versioned_hash = 12;
|
| 1071 |
-
bytes kzg_commitment = 13;
|
| 1072 |
-
bytes kzg_proof = 14;
|
| 1073 |
-
bytes point_z = 15;
|
| 1074 |
-
bytes point_y = 16;
|
| 1075 |
-
bytes blob_data = 17;
|
| 1076 |
-
bytes forced_hash_data = 18;
|
| 1077 |
-
string context_id = 19;
|
| 1078 |
-
DebugV3 debug = 20;
|
| 1079 |
-
map<string, string> db = 21;
|
| 1080 |
-
map<string, string> contracts_bytecode = 22; // For debug/testing purpposes only. Don't fill this on production
|
| 1081 |
-
}
|
| 1082 |
-
|
| 1083 |
-
message DebugV3 {
|
| 1084 |
-
bytes new_blob_state_root = 1;
|
| 1085 |
-
bytes new_blob_acc_input_hash = 2;
|
| 1086 |
-
uint64 new_blob_num = 3;
|
| 1087 |
-
}
|
| 1088 |
-
|
| 1089 |
-
message ProcessBlobInnerResponseV3 {
|
| 1090 |
-
// outputs
|
| 1091 |
-
bytes new_blob_state_root = 1;
|
| 1092 |
-
bytes new_blob_acc_input_hash = 2;
|
| 1093 |
-
uint64 new_num_blob = 3;
|
| 1094 |
-
bytes final_acc_batch_hash_data = 4;
|
| 1095 |
-
bytes local_exit_root_from_blob = 5;
|
| 1096 |
-
uint32 is_invalid = 6;
|
| 1097 |
-
// extra
|
| 1098 |
-
repeated bytes batch_data = 7;
|
| 1099 |
-
ExecutorError error = 8;
|
| 1100 |
-
RomBlobError error_rom_blob = 9;
|
| 1101 |
-
ResponseDebug debug = 10;
|
| 1102 |
-
}
|
| 1103 |
-
|
| 1104 |
-
enum RomBlobError {
|
| 1105 |
-
ROM_BLOB_ERROR_UNSPECIFIED = 0;
|
| 1106 |
-
// ROM_ERROR_NO_ERROR indicates the execution ended successfully
|
| 1107 |
-
ROM_BLOB_ERROR_NO_ERROR = 1;
|
| 1108 |
-
// ROM_BLOB_ERROR_INVALID_PARSING indicates that has been an error while parsing the blob data
|
| 1109 |
-
ROM_BLOB_ERROR_INVALID_PARSING = 2;
|
| 1110 |
-
// ROM_BLOB_ERROR_INVALID_MSB_BYTE indicates that the MSB on one field element is different than zero (only for blob_type = 1)
|
| 1111 |
-
ROM_BLOB_ERROR_INVALID_MSB_BYTE = 3;
|
| 1112 |
-
// ROM_BLOB_ERROR_INVALID_ZK_GAS_LIMIT not enough zk_gas_limit supplied to pay for batches proofs
|
| 1113 |
-
ROM_BLOB_ERROR_INVALID_ZK_GAS_LIMIT = 4;
|
| 1114 |
-
// ROM_BLOB_ERROR_INVALID_BLOB_TYPE blob_type not supported
|
| 1115 |
-
ROM_BLOB_ERROR_INVALID_BLOB_TYPE = 5;
|
| 1116 |
-
// ROM_BLOB_ERROR_INVALID_COMPRESSION_TYPE compression type not supported
|
| 1117 |
-
ROM_BLOB_ERROR_INVALID_COMPRESSION_TYPE = 6;
|
| 1118 |
-
// ROM_BLOB_ERROR_INVALID_FORCED_BATCHES blobtype = 2 and numBatches > 1
|
| 1119 |
-
ROM_BLOB_ERROR_INVALID_FORCED_BATCHES = 7;
|
| 1120 |
-
// ROM_BLOB_ERROR_INVALID_TOTALBODY_LEN totalBodyLen != blobDataLen - 1 (byte compression) - 4 (bytes totalBodyLen)
|
| 1121 |
-
ROM_BLOB_ERROR_INVALID_TOTALBODY_LEN = 8;
|
| 1122 |
-
}
|
|
|
|
| 10 |
/// Processes a batch
|
| 11 |
rpc ProcessBatch(ProcessBatchRequest) returns (ProcessBatchResponse) {}
|
| 12 |
rpc ProcessBatchV2(ProcessBatchRequestV2) returns (ProcessBatchResponseV2) {}
|
|
|
|
|
|
|
|
|
|
| 13 |
rpc GetFlushStatus (google.protobuf.Empty) returns (GetFlushStatusResponse) {}
|
| 14 |
}
|
| 15 |
|
|
|
|
| 292 |
// prior to executing the call.
|
| 293 |
map<string, OverrideAccountV2> state_override = 23;
|
| 294 |
DebugV2 debug = 24;
|
| 295 |
+
uint64 execution_mode = 25;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
}
|
| 297 |
|
| 298 |
message L1DataV2 {
|
|
|
|
| 304 |
|
| 305 |
message DebugV2 {
|
| 306 |
uint64 gas_limit = 1;
|
| 307 |
+
bytes new_state_root = 2;
|
| 308 |
bytes new_acc_input_hash = 3;
|
| 309 |
bytes new_local_exit_root = 4;
|
| 310 |
uint64 new_batch_num = 5;
|
|
|
|
| 343 |
uint32 cnt_reserve_binaries = 30;
|
| 344 |
uint32 cnt_reserve_steps = 31;
|
| 345 |
uint32 cnt_reserve_sha256_hashes = 32;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 346 |
}
|
| 347 |
|
| 348 |
// Trace configuration request params
|
|
|
|
| 383 |
string nonce = 1;
|
| 384 |
// If balance="" then it has not been set; if set, string is in decimal (base 10)
|
| 385 |
string balance = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
}
|
| 387 |
|
| 388 |
message FullTraceV2 {
|
|
|
|
| 636 |
ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_LIMIT_TIMESTAMP = 33;
|
| 637 |
// ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP indicates that the change l2 block transaction has trigger an error during while executing
|
| 638 |
ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP = 34;
|
|
|
|
|
|
|
| 639 |
}
|
| 640 |
|
| 641 |
enum ExecutorError {
|
|
|
|
| 875 |
EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE = 116;
|
| 876 |
// EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR indicates that a TX has an invalid status-error combination
|
| 877 |
EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR = 117;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 878 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -345,12 +344,16 @@
|
|
| 345 |
|
| 346 |
// Log batch detailed info
|
| 347 |
log.Errorf("batch %d sanity check error: initialStateRoot: %s, expectedNewStateRoot: %s", batch.BatchNumber, initialStateRoot, expectedNewStateRoot)
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
|
|
|
|
|
|
|
|
|
| 352 |
}
|
| 353 |
}
|
|
|
|
| 354 |
|
| 355 |
f.Halt(ctx, fmt.Errorf("batch sanity check error. Check previous errors in logs to know which was the cause"), false)
|
| 356 |
}
|
|
|
|
| 344 |
|
| 345 |
// Log batch detailed info
|
| 346 |
log.Errorf("batch %d sanity check error: initialStateRoot: %s, expectedNewStateRoot: %s", batch.BatchNumber, initialStateRoot, expectedNewStateRoot)
|
| 347 |
+
batchLog := ""
|
| 348 |
+
totalTxs := 0
|
| 349 |
+
for blockIdx, rawL2block := range rawL2Blocks.Blocks {
|
| 350 |
+
totalTxs += len(rawL2block.Transactions)
|
| 351 |
+
batchLog += fmt.Sprintf("block[%d], txs: %d, deltaTimestamp: %d, l1InfoTreeIndex: %d\n", blockIdx, len(rawL2block.Transactions), rawL2block.DeltaTimestamp, rawL2block.IndexL1InfoTree)
|
| 352 |
+
for txIdx, rawTx := range rawL2block.Transactions {
|
| 353 |
+
batchLog += fmt.Sprintf(" tx[%d]: %s, egpPct: %d\n", txIdx, rawTx.Tx.Hash(), rawTx.EfficiencyPercentage)
|
| 354 |
}
|
| 355 |
}
|
| 356 |
+
log.Infof("DUMP batch %d, blocks: %d, txs: %d\n%s", batch.BatchNumber, len(rawL2Blocks.Blocks), totalTxs, batchLog)
|
| 357 |
|
| 358 |
f.Halt(ctx, fmt.Errorf("batch sanity check error. Check previous errors in logs to know which was the cause"), false)
|
| 359 |
}
|
|
@@ -42,6 +43,7 @@
|
|
| 42 |
l2Transactions = append(l2Transactions, l2Transaction)
|
| 43 |
}
|
| 44 |
|
|
|
|
| 45 |
f.dataToStream <- state.DSL2FullBlock{
|
| 46 |
DSL2Block: l2Block,
|
| 47 |
Txs: l2Transactions,
|
|
|
|
| 43 |
l2Transactions = append(l2Transactions, l2Transaction)
|
| 44 |
}
|
| 45 |
|
| 46 |
+
log.Infof("sending l2block %d to datastream channel", blockResponse.BlockNumber)
|
| 47 |
f.dataToStream <- state.DSL2FullBlock{
|
| 48 |
DSL2Block: l2Block,
|
| 49 |
Txs: l2Transactions,
|
|
@@ -242,15 +242,15 @@
|
|
| 242 |
return false, nil
|
| 243 |
}
|
| 244 |
|
| 245 |
-
// Check l1InfoRootIndex and GER matches
|
| 246 |
-
//
|
| 247 |
log.Debugf("getting l1InfoRoot events for L1 block %d, hash: %s", l1InfoRoot.BlockNumber, l1BlockState.BlockHash)
|
| 248 |
blocks, eventsOrder, err := f.etherman.GetRollupInfoByBlockRange(ctx, l1InfoRoot.BlockNumber, &l1InfoRoot.BlockNumber)
|
| 249 |
if err != nil {
|
| 250 |
return false, err
|
| 251 |
}
|
| 252 |
|
| 253 |
-
//
|
| 254 |
lastGER := state.ZeroHash
|
| 255 |
for _, block := range blocks {
|
| 256 |
blockEventsOrder := eventsOrder[block.BlockHash]
|
|
@@ -394,7 +394,8 @@
|
|
| 394 |
firstTxProcess := true
|
| 395 |
|
| 396 |
for {
|
| 397 |
-
|
|
|
|
| 398 |
if err != nil {
|
| 399 |
if err == ErrEffectiveGasPriceReprocess {
|
| 400 |
firstTxProcess = false
|
|
@@ -466,6 +467,7 @@
|
|
| 466 |
SkipWriteBlockInfoRoot_V2: true,
|
| 467 |
SkipVerifyL1InfoRoot_V2: true,
|
| 468 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
|
|
|
| 469 |
}
|
| 470 |
|
| 471 |
txGasPrice := tx.GasPrice
|
|
@@ -512,7 +514,7 @@
|
|
| 512 |
}
|
| 513 |
}
|
| 514 |
|
| 515 |
-
egpPercentage, err :=
|
| 516 |
if err != nil {
|
| 517 |
if f.effectiveGasPrice.IsEnabled() {
|
| 518 |
return nil, err
|
|
@@ -625,7 +627,7 @@
|
|
| 625 |
|
| 626 |
// If EffectiveGasPrice is disabled we will calculate the percentage and save it for later logging
|
| 627 |
if !egpEnabled {
|
| 628 |
-
effectivePercentage, err :=
|
| 629 |
if err != nil {
|
| 630 |
log.Warnf("effectiveGasPrice is disabled, but failed to calculate effective gas price percentage (#2), error: %v", err)
|
| 631 |
tx.EGPLog.Error = fmt.Sprintf("%s, CalculateEffectiveGasPricePercentage#2: %s", tx.EGPLog.Error, err)
|
|
|
|
| 242 |
return false, nil
|
| 243 |
}
|
| 244 |
|
| 245 |
+
// Check l1InfoRootIndex and GER matches. We retrieve the info of the last l1InfoTree event in the block, since in the case we have several l1InfoTree events
|
| 246 |
+
// in the same block, the function checkL1InfoTreeUpdate retrieves only the last one and skips the others
|
| 247 |
log.Debugf("getting l1InfoRoot events for L1 block %d, hash: %s", l1InfoRoot.BlockNumber, l1BlockState.BlockHash)
|
| 248 |
blocks, eventsOrder, err := f.etherman.GetRollupInfoByBlockRange(ctx, l1InfoRoot.BlockNumber, &l1InfoRoot.BlockNumber)
|
| 249 |
if err != nil {
|
| 250 |
return false, err
|
| 251 |
}
|
| 252 |
|
| 253 |
+
//Get L1InfoTree events of the L1 block where the l1InforRoot we need to check was synced
|
| 254 |
lastGER := state.ZeroHash
|
| 255 |
for _, block := range blocks {
|
| 256 |
blockEventsOrder := eventsOrder[block.BlockHash]
|
|
|
|
| 394 |
firstTxProcess := true
|
| 395 |
|
| 396 |
for {
|
| 397 |
+
var err error
|
| 398 |
+
_, err = f.processTransaction(ctx, tx, firstTxProcess)
|
| 399 |
if err != nil {
|
| 400 |
if err == ErrEffectiveGasPriceReprocess {
|
| 401 |
firstTxProcess = false
|
|
|
|
| 467 |
SkipWriteBlockInfoRoot_V2: true,
|
| 468 |
SkipVerifyL1InfoRoot_V2: true,
|
| 469 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
| 470 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 471 |
}
|
| 472 |
|
| 473 |
txGasPrice := tx.GasPrice
|
|
|
|
| 514 |
}
|
| 515 |
}
|
| 516 |
|
| 517 |
+
egpPercentage, err := state.CalculateEffectiveGasPricePercentage(txGasPrice, tx.EffectiveGasPrice)
|
| 518 |
if err != nil {
|
| 519 |
if f.effectiveGasPrice.IsEnabled() {
|
| 520 |
return nil, err
|
|
|
|
| 627 |
|
| 628 |
// If EffectiveGasPrice is disabled we will calculate the percentage and save it for later logging
|
| 629 |
if !egpEnabled {
|
| 630 |
+
effectivePercentage, err := state.CalculateEffectiveGasPricePercentage(txGasPrice, tx.EffectiveGasPrice)
|
| 631 |
if err != nil {
|
| 632 |
log.Warnf("effectiveGasPrice is disabled, but failed to calculate effective gas price percentage (#2), error: %v", err)
|
| 633 |
tx.EGPLog.Error = fmt.Sprintf("%s, CalculateEffectiveGasPricePercentage#2: %s", tx.EGPLog.Error, err)
|
|
@@ -283,6 +284,7 @@
|
|
| 283 |
ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber),
|
| 284 |
SkipVerifyL1InfoRoot_V2: true,
|
| 285 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
|
|
|
| 286 |
}
|
| 287 |
batchRequest.L1InfoTreeData_V2[l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
| 288 |
GlobalExitRoot: l2Block.l1InfoTreeExitRoot.GlobalExitRoot.GlobalExitRoot,
|
|
@@ -310,7 +312,7 @@
|
|
| 310 |
}
|
| 311 |
|
| 312 |
if batchResponse.IsRomOOCError {
|
| 313 |
-
executeL2BLockError(
|
| 314 |
return nil, 0, ErrProcessBatchOOC
|
| 315 |
}
|
| 316 |
|
|
@@ -411,6 +413,9 @@
|
|
| 411 |
return err
|
| 412 |
}
|
| 413 |
|
|
|
|
|
|
|
|
|
|
| 414 |
// Update txs status in the pool
|
| 415 |
for _, txResponse := range blockResponse.TransactionResponses {
|
| 416 |
// Change Tx status to selected
|
|
@@ -420,6 +425,9 @@
|
|
| 420 |
}
|
| 421 |
}
|
| 422 |
|
|
|
|
|
|
|
|
|
|
| 423 |
// Send L2 block to data streamer
|
| 424 |
err = f.DSSendL2Block(f.wipBatch.batchNumber, blockResponse, l2Block.getL1InfoTreeIndex())
|
| 425 |
if err != nil {
|
|
@@ -427,6 +435,9 @@
|
|
| 427 |
log.Errorf("error sending L2 block %d [%d] to data streamer, error: %v", blockResponse.BlockNumber, l2Block.trackingNum, err)
|
| 428 |
}
|
| 429 |
|
|
|
|
|
|
|
|
|
|
| 430 |
for _, tx := range l2Block.transactions {
|
| 431 |
// Delete the tx from the pending list in the worker (addrQueue)
|
| 432 |
f.workerIntf.DeletePendingTxToStore(tx.Hash, tx.From)
|
|
@@ -582,6 +593,7 @@
|
|
| 582 |
SkipFirstChangeL2Block_V2: false,
|
| 583 |
Transactions: f.stateIntf.BuildChangeL2Block(f.wipL2Block.deltaTimestamp, f.wipL2Block.getL1InfoTreeIndex()),
|
| 584 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
|
|
|
| 585 |
}
|
| 586 |
|
| 587 |
batchRequest.L1InfoTreeData_V2[f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
|
|
|
| 284 |
ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber),
|
| 285 |
SkipVerifyL1InfoRoot_V2: true,
|
| 286 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
| 287 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 288 |
}
|
| 289 |
batchRequest.L1InfoTreeData_V2[l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
| 290 |
GlobalExitRoot: l2Block.l1InfoTreeExitRoot.GlobalExitRoot.GlobalExitRoot,
|
|
|
|
| 312 |
}
|
| 313 |
|
| 314 |
if batchResponse.IsRomOOCError {
|
| 315 |
+
executeL2BLockError(batchResponse.RomError_V2)
|
| 316 |
return nil, 0, ErrProcessBatchOOC
|
| 317 |
}
|
| 318 |
|
|
|
|
| 413 |
return err
|
| 414 |
}
|
| 415 |
|
| 416 |
+
//TODO: remove this log
|
| 417 |
+
log.Infof("l2 block %d [%d] stored in statedb", blockResponse.BlockNumber, l2Block.trackingNum)
|
| 418 |
+
|
| 419 |
// Update txs status in the pool
|
| 420 |
for _, txResponse := range blockResponse.TransactionResponses {
|
| 421 |
// Change Tx status to selected
|
|
|
|
| 425 |
}
|
| 426 |
}
|
| 427 |
|
| 428 |
+
//TODO: remove this log
|
| 429 |
+
log.Infof("l2 block %d [%d] transactions updated as selected in the pooldb", blockResponse.BlockNumber, l2Block.trackingNum)
|
| 430 |
+
|
| 431 |
// Send L2 block to data streamer
|
| 432 |
err = f.DSSendL2Block(f.wipBatch.batchNumber, blockResponse, l2Block.getL1InfoTreeIndex())
|
| 433 |
if err != nil {
|
|
|
|
| 435 |
log.Errorf("error sending L2 block %d [%d] to data streamer, error: %v", blockResponse.BlockNumber, l2Block.trackingNum, err)
|
| 436 |
}
|
| 437 |
|
| 438 |
+
//TODO: remove this log
|
| 439 |
+
log.Infof("l2 block %d [%d] sent to datastream", blockResponse.BlockNumber, l2Block.trackingNum)
|
| 440 |
+
|
| 441 |
for _, tx := range l2Block.transactions {
|
| 442 |
// Delete the tx from the pending list in the worker (addrQueue)
|
| 443 |
f.workerIntf.DeletePendingTxToStore(tx.Hash, tx.From)
|
|
|
|
| 593 |
SkipFirstChangeL2Block_V2: false,
|
| 594 |
Transactions: f.stateIntf.BuildChangeL2Block(f.wipL2Block.deltaTimestamp, f.wipL2Block.getL1InfoTreeIndex()),
|
| 595 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
| 596 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 597 |
}
|
| 598 |
|
| 599 |
batchRequest.L1InfoTreeData_V2[f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
|
@@ -256,6 +256,8 @@
|
|
| 256 |
case state.DSL2FullBlock:
|
| 257 |
l2Block := data
|
| 258 |
|
|
|
|
|
|
|
| 259 |
err = s.streamServer.StartAtomicOp()
|
| 260 |
if err != nil {
|
| 261 |
log.Errorf("failed to start atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
|
@@ -267,6 +269,8 @@
|
|
| 267 |
Value: l2Block.L2BlockNumber,
|
| 268 |
}
|
| 269 |
|
|
|
|
|
|
|
| 270 |
_, err = s.streamServer.AddStreamBookmark(bookMark.Encode())
|
| 271 |
if err != nil {
|
| 272 |
log.Errorf("failed to add stream bookmark for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
|
@@ -281,6 +285,8 @@
|
|
| 281 |
Value: l2Block.L2BlockNumber - 1,
|
| 282 |
}
|
| 283 |
|
|
|
|
|
|
|
| 284 |
previousL2BlockEntry, err := s.streamServer.GetFirstEventAfterBookmark(bookMark.Encode())
|
| 285 |
if err != nil {
|
| 286 |
log.Errorf("failed to get previous l2block %d, error: %v", l2Block.L2BlockNumber-1, err)
|
|
@@ -303,12 +309,16 @@
|
|
| 303 |
ChainID: uint32(chainID),
|
| 304 |
}
|
| 305 |
|
|
|
|
|
|
|
| 306 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockStart, blockStart.Encode())
|
| 307 |
if err != nil {
|
| 308 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 309 |
continue
|
| 310 |
}
|
| 311 |
|
|
|
|
|
|
|
| 312 |
for _, l2Transaction := range l2Block.Txs {
|
| 313 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2Tx, l2Transaction.Encode())
|
| 314 |
if err != nil {
|
|
@@ -323,18 +333,25 @@
|
|
| 323 |
StateRoot: l2Block.StateRoot,
|
| 324 |
}
|
| 325 |
|
|
|
|
|
|
|
| 326 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockEnd, blockEnd.Encode())
|
| 327 |
if err != nil {
|
| 328 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 329 |
continue
|
| 330 |
}
|
| 331 |
|
|
|
|
|
|
|
| 332 |
err = s.streamServer.CommitAtomicOp()
|
| 333 |
if err != nil {
|
| 334 |
log.Errorf("failed to commit atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
| 335 |
continue
|
| 336 |
}
|
| 337 |
|
|
|
|
|
|
|
|
|
|
| 338 |
// Stream a bookmark
|
| 339 |
case state.DSBookMark:
|
| 340 |
bookmark := data
|
|
|
|
| 256 |
case state.DSL2FullBlock:
|
| 257 |
l2Block := data
|
| 258 |
|
| 259 |
+
//TODO: remove this log
|
| 260 |
+
log.Infof("start atomic op for l2block %d", l2Block.L2BlockNumber)
|
| 261 |
err = s.streamServer.StartAtomicOp()
|
| 262 |
if err != nil {
|
| 263 |
log.Errorf("failed to start atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
|
|
|
| 269 |
Value: l2Block.L2BlockNumber,
|
| 270 |
}
|
| 271 |
|
| 272 |
+
//TODO: remove this log
|
| 273 |
+
log.Infof("add stream bookmark for l2block %d", l2Block.L2BlockNumber)
|
| 274 |
_, err = s.streamServer.AddStreamBookmark(bookMark.Encode())
|
| 275 |
if err != nil {
|
| 276 |
log.Errorf("failed to add stream bookmark for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
|
|
|
| 285 |
Value: l2Block.L2BlockNumber - 1,
|
| 286 |
}
|
| 287 |
|
| 288 |
+
//TODO: remove this log
|
| 289 |
+
log.Infof("get previous l2block %d", l2Block.L2BlockNumber-1)
|
| 290 |
previousL2BlockEntry, err := s.streamServer.GetFirstEventAfterBookmark(bookMark.Encode())
|
| 291 |
if err != nil {
|
| 292 |
log.Errorf("failed to get previous l2block %d, error: %v", l2Block.L2BlockNumber-1, err)
|
|
|
|
| 309 |
ChainID: uint32(chainID),
|
| 310 |
}
|
| 311 |
|
| 312 |
+
//TODO: remove this log
|
| 313 |
+
log.Infof("add l2blockStart stream entry for l2block %d", l2Block.L2BlockNumber)
|
| 314 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockStart, blockStart.Encode())
|
| 315 |
if err != nil {
|
| 316 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 317 |
continue
|
| 318 |
}
|
| 319 |
|
| 320 |
+
//TODO: remove this log
|
| 321 |
+
log.Infof("adding l2tx stream entries for l2block %d", l2Block.L2BlockNumber)
|
| 322 |
for _, l2Transaction := range l2Block.Txs {
|
| 323 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2Tx, l2Transaction.Encode())
|
| 324 |
if err != nil {
|
|
|
|
| 333 |
StateRoot: l2Block.StateRoot,
|
| 334 |
}
|
| 335 |
|
| 336 |
+
//TODO: remove this log
|
| 337 |
+
log.Infof("add l2blockEnd stream entry for l2block %d", l2Block.L2BlockNumber)
|
| 338 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockEnd, blockEnd.Encode())
|
| 339 |
if err != nil {
|
| 340 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 341 |
continue
|
| 342 |
}
|
| 343 |
|
| 344 |
+
//TODO: remove this log
|
| 345 |
+
log.Infof("commit atomic op for l2block %d", l2Block.L2BlockNumber)
|
| 346 |
err = s.streamServer.CommitAtomicOp()
|
| 347 |
if err != nil {
|
| 348 |
log.Errorf("failed to commit atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
| 349 |
continue
|
| 350 |
}
|
| 351 |
|
| 352 |
+
//TODO: remove this log
|
| 353 |
+
log.Infof("l2block %d sent to datastream", l2Block.L2BlockNumber)
|
| 354 |
+
|
| 355 |
// Stream a bookmark
|
| 356 |
case state.DSBookMark:
|
| 357 |
bookmark := data
|
|
@@ -41,4 +41,6 @@
|
|
| 41 |
// gas offset: 100
|
| 42 |
// final gas: 1100
|
| 43 |
GasOffset uint64 `mapstructure:"GasOffset"`
|
|
|
|
|
|
|
| 44 |
}
|
|
|
|
| 41 |
// gas offset: 100
|
| 42 |
// final gas: 1100
|
| 43 |
GasOffset uint64 `mapstructure:"GasOffset"`
|
| 44 |
+
// MaxBatchesForL1 is the maximum amount of batches to be sequenced in a single L1 tx
|
| 45 |
+
MaxBatchesForL1 uint64 `mapstructure:"MaxBatchesForL1"`
|
| 46 |
}
|
|
@@ -17,8 +17,8 @@
|
|
| 17 |
|
| 18 |
// etherman contains the methods required to interact with ethereum.
|
| 19 |
type etherman interface {
|
| 20 |
-
BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (to *common.Address, data []byte, err error)
|
| 21 |
-
EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error)
|
| 22 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
| 23 |
GetLatestBatchNumber() (uint64, error)
|
| 24 |
}
|
|
@@ -41,3 +41,7 @@
|
|
| 41 |
Add(ctx context.Context, owner, id string, from common.Address, to *common.Address, value *big.Int, data []byte, gasOffset uint64, dbTx pgx.Tx) error
|
| 42 |
ProcessPendingMonitoredTxs(ctx context.Context, owner string, failedResultHandler ethtxmanager.ResultHandler, dbTx pgx.Tx)
|
| 43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
// etherman contains the methods required to interact with ethereum.
|
| 19 |
type etherman interface {
|
| 20 |
+
BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address, committeeSignaturesAndAddrs []byte) (to *common.Address, data []byte, err error)
|
| 21 |
+
EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address, committeeSignaturesAndAddrs []byte) (*types.Transaction, error)
|
| 22 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
| 23 |
GetLatestBatchNumber() (uint64, error)
|
| 24 |
}
|
|
|
|
| 41 |
Add(ctx context.Context, owner, id string, from common.Address, to *common.Address, value *big.Int, data []byte, gasOffset uint64, dbTx pgx.Tx) error
|
| 42 |
ProcessPendingMonitoredTxs(ctx context.Context, owner string, failedResultHandler ethtxmanager.ResultHandler, dbTx pgx.Tx)
|
| 43 |
}
|
| 44 |
+
|
| 45 |
+
type dataAbilitier interface {
|
| 46 |
+
PostSequence(ctx context.Context, sequences []ethmanTypes.Sequence) ([]byte, error)
|
| 47 |
+
}
|
|
@@ -6,13 +6,11 @@
|
|
| 6 |
"fmt"
|
| 7 |
"time"
|
| 8 |
|
| 9 |
-
ethman "github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 10 |
"github.com/0xPolygonHermez/zkevm-node/etherman/types"
|
| 11 |
"github.com/0xPolygonHermez/zkevm-node/ethtxmanager"
|
| 12 |
"github.com/0xPolygonHermez/zkevm-node/event"
|
| 13 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 14 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 15 |
-
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
| 16 |
"github.com/jackc/pgx/v4"
|
| 17 |
)
|
| 18 |
|
|
@@ -41,16 +39,18 @@
|
|
| 41 |
ethTxManager ethTxManager
|
| 42 |
etherman etherman
|
| 43 |
eventLog *event.EventLog
|
|
|
|
| 44 |
}
|
| 45 |
|
| 46 |
// New inits sequence sender
|
| 47 |
-
func New(cfg Config, state stateInterface, etherman etherman, manager ethTxManager, eventLog *event.EventLog) (*SequenceSender, error) {
|
| 48 |
return &SequenceSender{
|
| 49 |
cfg: cfg,
|
| 50 |
state: state,
|
| 51 |
etherman: etherman,
|
| 52 |
ethTxManager: manager,
|
| 53 |
eventLog: eventLog,
|
|
|
|
| 54 |
}, nil
|
| 55 |
}
|
| 56 |
|
|
@@ -185,9 +185,14 @@
|
|
| 185 |
}
|
| 186 |
|
| 187 |
// add sequence to be monitored
|
| 188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
|
| 190 |
-
|
|
|
|
| 191 |
if err != nil {
|
| 192 |
log.Error("error estimating new sequenceBatches to add to eth tx manager: ", err)
|
| 193 |
return
|
|
@@ -208,7 +213,7 @@
|
|
| 208 |
func (s *SequenceSender) getSequencesToSend(ctx context.Context) ([]types.Sequence, error) {
|
| 209 |
lastVirtualBatchNum, err := s.state.GetLastVirtualBatchNum(ctx, nil)
|
| 210 |
if err != nil {
|
| 211 |
-
return nil, fmt.Errorf("failed to get last virtual batch num, err: %
|
| 212 |
}
|
| 213 |
log.Debugf("last virtual batch number: %d", lastVirtualBatchNum)
|
| 214 |
|
|
@@ -218,8 +223,6 @@
|
|
| 218 |
sequences := []types.Sequence{}
|
| 219 |
// var estimatedGas uint64
|
| 220 |
|
| 221 |
-
var tx *ethTypes.Transaction
|
| 222 |
-
|
| 223 |
// Add sequences until too big for a single L1 tx or last batch is reached
|
| 224 |
for {
|
| 225 |
//Check if the next batch belongs to a new forkid, in this case we need to stop sequencing as we need to
|
|
@@ -234,14 +237,14 @@
|
|
| 234 |
if err == state.ErrNotFound {
|
| 235 |
break
|
| 236 |
}
|
| 237 |
-
log.Debugf("failed to get batch by number %d, err: %
|
| 238 |
return nil, err
|
| 239 |
}
|
| 240 |
|
| 241 |
// Check if batch is closed and checked (sequencer sanity check was successful)
|
| 242 |
isChecked, err := s.state.IsBatchChecked(ctx, currentBatchNumToSequence, nil)
|
| 243 |
if err != nil {
|
| 244 |
-
log.Debugf("failed to check if batch %d is closed and checked, err: %
|
| 245 |
return nil, err
|
| 246 |
}
|
| 247 |
|
|
@@ -288,31 +291,11 @@
|
|
| 288 |
|
| 289 |
sequences = append(sequences, seq)
|
| 290 |
// Check if can be send
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
err = ErrOversizedData
|
| 297 |
-
}
|
| 298 |
-
if err != nil {
|
| 299 |
-
log.Infof("Handling estimage gas send sequence error: %v", err)
|
| 300 |
-
sequences, err = s.handleEstimateGasSendSequenceErr(ctx, sequences, currentBatchNumToSequence, err)
|
| 301 |
-
if sequences != nil {
|
| 302 |
-
if len(sequences) > 0 {
|
| 303 |
-
// Handling the error gracefully, re-processing the sequence as a sanity check
|
| 304 |
-
lastSequence = sequences[len(sequences)-1]
|
| 305 |
-
_, err = s.etherman.EstimateGasSequenceBatches(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase)
|
| 306 |
-
return sequences, err
|
| 307 |
-
}
|
| 308 |
-
}
|
| 309 |
-
return sequences, err
|
| 310 |
-
}
|
| 311 |
-
// estimatedGas = tx.Gas()
|
| 312 |
-
|
| 313 |
-
//Check if the current batch is the last before a change to a new forkid, in this case we need to close and send the sequence to L1
|
| 314 |
-
if (s.cfg.ForkUpgradeBatchNumber != 0) && (currentBatchNumToSequence == (s.cfg.ForkUpgradeBatchNumber)) {
|
| 315 |
-
log.Infof("sequence should be sent to L1, as we have reached the batch %d from which a new forkid is applied (upgrade)", s.cfg.ForkUpgradeBatchNumber)
|
| 316 |
return sequences, nil
|
| 317 |
}
|
| 318 |
|
|
@@ -343,78 +326,6 @@
|
|
| 343 |
return nil, nil
|
| 344 |
}
|
| 345 |
|
| 346 |
-
// handleEstimateGasSendSequenceErr handles an error on the estimate gas. It will return:
|
| 347 |
-
// nil, error: impossible to handle gracefully
|
| 348 |
-
// sequence, nil: handled gracefully. Potentially manipulating the sequences
|
| 349 |
-
// nil, nil: a situation that requires waiting
|
| 350 |
-
func (s *SequenceSender) handleEstimateGasSendSequenceErr(
|
| 351 |
-
ctx context.Context,
|
| 352 |
-
sequences []types.Sequence,
|
| 353 |
-
currentBatchNumToSequence uint64,
|
| 354 |
-
err error,
|
| 355 |
-
) ([]types.Sequence, error) {
|
| 356 |
-
// Insufficient allowance
|
| 357 |
-
if errors.Is(err, ethman.ErrInsufficientAllowance) {
|
| 358 |
-
return nil, err
|
| 359 |
-
}
|
| 360 |
-
if isDataForEthTxTooBig(err) {
|
| 361 |
-
// Remove the latest item and send the sequences
|
| 362 |
-
log.Infof(
|
| 363 |
-
"Done building sequences, selected batches to %d. Batch %d caused the L1 tx to be too big",
|
| 364 |
-
currentBatchNumToSequence-1, currentBatchNumToSequence,
|
| 365 |
-
)
|
| 366 |
-
sequences = sequences[:len(sequences)-1]
|
| 367 |
-
return sequences, nil
|
| 368 |
-
}
|
| 369 |
-
|
| 370 |
-
// while estimating gas a new block is not created and the POE SC may return
|
| 371 |
-
// an error regarding timestamp verification, this must be handled
|
| 372 |
-
// if errors.Is(err, ethman.ErrTimestampMustBeInsideRange) {
|
| 373 |
-
// // query the sc about the value of its lastTimestamp variable
|
| 374 |
-
// lastTimestamp, err := s.etherman.GetLastBatchTimestamp()
|
| 375 |
-
// if err != nil {
|
| 376 |
-
// return nil, err
|
| 377 |
-
// }
|
| 378 |
-
// // check POE SC lastTimestamp against sequences' one
|
| 379 |
-
// for _, seq := range sequences {
|
| 380 |
-
// if seq.Timestamp < int64(lastTimestamp) {
|
| 381 |
-
// // TODO: gracefully handle this situation by creating an L2 reorg
|
| 382 |
-
// log.Fatalf("sequence timestamp %d is < POE SC lastTimestamp %d", seq.Timestamp, lastTimestamp)
|
| 383 |
-
// }
|
| 384 |
-
// lastTimestamp = uint64(seq.Timestamp)
|
| 385 |
-
// }
|
| 386 |
-
// blockTimestamp, err := s.etherman.GetLatestBlockTimestamp(ctx)
|
| 387 |
-
// if err != nil {
|
| 388 |
-
// log.Error("error getting block timestamp: ", err)
|
| 389 |
-
// }
|
| 390 |
-
// log.Debugf("block.timestamp: %d is smaller than seq.Timestamp: %d. A new block must be mined in L1 before the gas can be estimated.", blockTimestamp, sequences[0].Timestamp)
|
| 391 |
-
// return nil, nil
|
| 392 |
-
// }
|
| 393 |
-
|
| 394 |
-
// Unknown error
|
| 395 |
-
if len(sequences) == 1 {
|
| 396 |
-
// TODO: gracefully handle this situation by creating an L2 reorg
|
| 397 |
-
log.Errorf(
|
| 398 |
-
"Error when estimating gas for BatchNum %d (alone in the sequences): %v",
|
| 399 |
-
currentBatchNumToSequence, err,
|
| 400 |
-
)
|
| 401 |
-
}
|
| 402 |
-
// Remove the latest item and send the sequences
|
| 403 |
-
log.Infof(
|
| 404 |
-
"Done building sequences, selected batches to %d. Batch %d excluded due to unknown error: %v",
|
| 405 |
-
currentBatchNumToSequence, currentBatchNumToSequence+1, err,
|
| 406 |
-
)
|
| 407 |
-
sequences = sequences[:len(sequences)-1]
|
| 408 |
-
|
| 409 |
-
return sequences, nil
|
| 410 |
-
}
|
| 411 |
-
|
| 412 |
-
func isDataForEthTxTooBig(err error) bool {
|
| 413 |
-
return errors.Is(err, ethman.ErrGasRequiredExceedsAllowance) ||
|
| 414 |
-
errors.Is(err, ErrOversizedData) ||
|
| 415 |
-
errors.Is(err, ethman.ErrContentLengthTooLarge)
|
| 416 |
-
}
|
| 417 |
-
|
| 418 |
func (s *SequenceSender) isSynced(ctx context.Context, retries int, waitRetry time.Duration) (bool, error) {
|
| 419 |
lastVirtualBatchNum, err := s.state.GetLastVirtualBatchNum(ctx, nil)
|
| 420 |
if err != nil && err != state.ErrNotFound {
|
|
|
|
| 6 |
"fmt"
|
| 7 |
"time"
|
| 8 |
|
|
|
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/etherman/types"
|
| 10 |
"github.com/0xPolygonHermez/zkevm-node/ethtxmanager"
|
| 11 |
"github.com/0xPolygonHermez/zkevm-node/event"
|
| 12 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 13 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
|
|
|
| 14 |
"github.com/jackc/pgx/v4"
|
| 15 |
)
|
| 16 |
|
|
|
|
| 39 |
ethTxManager ethTxManager
|
| 40 |
etherman etherman
|
| 41 |
eventLog *event.EventLog
|
| 42 |
+
da dataAbilitier
|
| 43 |
}
|
| 44 |
|
| 45 |
// New inits sequence sender
|
| 46 |
+
func New(cfg Config, state stateInterface, etherman etherman, manager ethTxManager, eventLog *event.EventLog, da dataAbilitier) (*SequenceSender, error) {
|
| 47 |
return &SequenceSender{
|
| 48 |
cfg: cfg,
|
| 49 |
state: state,
|
| 50 |
etherman: etherman,
|
| 51 |
ethTxManager: manager,
|
| 52 |
eventLog: eventLog,
|
| 53 |
+
da: da,
|
| 54 |
}, nil
|
| 55 |
}
|
| 56 |
|
|
|
|
| 185 |
}
|
| 186 |
|
| 187 |
// add sequence to be monitored
|
| 188 |
+
dataAvailabilityMessage, err := s.da.PostSequence(ctx, sequences)
|
| 189 |
+
if err != nil {
|
| 190 |
+
log.Error("error posting sequences to the data availability protocol: ", err)
|
| 191 |
+
return
|
| 192 |
+
}
|
| 193 |
|
| 194 |
+
firstSequence := sequences[0]
|
| 195 |
+
to, data, err := s.etherman.BuildSequenceBatchesTxData(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase, dataAvailabilityMessage)
|
| 196 |
if err != nil {
|
| 197 |
log.Error("error estimating new sequenceBatches to add to eth tx manager: ", err)
|
| 198 |
return
|
|
|
|
| 213 |
func (s *SequenceSender) getSequencesToSend(ctx context.Context) ([]types.Sequence, error) {
|
| 214 |
lastVirtualBatchNum, err := s.state.GetLastVirtualBatchNum(ctx, nil)
|
| 215 |
if err != nil {
|
| 216 |
+
return nil, fmt.Errorf("failed to get last virtual batch num, err: %v", err)
|
| 217 |
}
|
| 218 |
log.Debugf("last virtual batch number: %d", lastVirtualBatchNum)
|
| 219 |
|
|
|
|
| 223 |
sequences := []types.Sequence{}
|
| 224 |
// var estimatedGas uint64
|
| 225 |
|
|
|
|
|
|
|
| 226 |
// Add sequences until too big for a single L1 tx or last batch is reached
|
| 227 |
for {
|
| 228 |
//Check if the next batch belongs to a new forkid, in this case we need to stop sequencing as we need to
|
|
|
|
| 237 |
if err == state.ErrNotFound {
|
| 238 |
break
|
| 239 |
}
|
| 240 |
+
log.Debugf("failed to get batch by number %d, err: %v", currentBatchNumToSequence, err)
|
| 241 |
return nil, err
|
| 242 |
}
|
| 243 |
|
| 244 |
// Check if batch is closed and checked (sequencer sanity check was successful)
|
| 245 |
isChecked, err := s.state.IsBatchChecked(ctx, currentBatchNumToSequence, nil)
|
| 246 |
if err != nil {
|
| 247 |
+
log.Debugf("failed to check if batch %d is closed and checked, err: %v", currentBatchNumToSequence, err)
|
| 248 |
return nil, err
|
| 249 |
}
|
| 250 |
|
|
|
|
| 291 |
|
| 292 |
sequences = append(sequences, seq)
|
| 293 |
// Check if can be send
|
| 294 |
+
if len(sequences) == int(s.cfg.MaxBatchesForL1) {
|
| 295 |
+
log.Info(
|
| 296 |
+
"sequence should be sent to L1, because MaxBatchesForL1 (%d) has been reached",
|
| 297 |
+
s.cfg.MaxBatchesForL1,
|
| 298 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
return sequences, nil
|
| 300 |
}
|
| 301 |
|
|
|
|
| 326 |
return nil, nil
|
| 327 |
}
|
| 328 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 329 |
func (s *SequenceSender) isSynced(ctx context.Context, retries int, waitRetry time.Duration) (bool, error) {
|
| 330 |
lastVirtualBatchNum, err := s.state.GetLastVirtualBatchNum(ctx, nil)
|
| 331 |
if err != nil && err != state.ErrNotFound {
|
|
@@ -30,7 +30,7 @@
|
|
| 30 |
stateMock := new(StateMock)
|
| 31 |
ethermanMock := new(EthermanMock)
|
| 32 |
ethTxManagerMock := new(EthTxManagerMock)
|
| 33 |
-
ssender, err := New(Config{}, stateMock, ethermanMock, ethTxManagerMock, nil)
|
| 34 |
assert.NoError(t, err)
|
| 35 |
|
| 36 |
testCases := []IsSyncedTestCase{
|
|
|
|
| 30 |
stateMock := new(StateMock)
|
| 31 |
ethermanMock := new(EthermanMock)
|
| 32 |
ethTxManagerMock := new(EthTxManagerMock)
|
| 33 |
+
ssender, err := New(Config{}, stateMock, ethermanMock, ethTxManagerMock, nil, nil)
|
| 34 |
assert.NoError(t, err)
|
| 35 |
|
| 36 |
testCases := []IsSyncedTestCase{
|
|
@@ -1,15 +1,10 @@
|
|
| 1 |
-
sonar.projectKey=
|
| 2 |
-
sonar.organization=0xpolygonhermez
|
| 3 |
|
| 4 |
sonar.sources=.
|
| 5 |
sonar.exclusions=**/*_test.go
|
| 6 |
-
sonar.exclusions=**/mock_*.go
|
| 7 |
|
| 8 |
sonar.tests=.
|
| 9 |
sonar.test.inclusions=**/*_test.go
|
| 10 |
-
sonar.test.exclusions=**/mock_*.go, **/mock/**
|
| 11 |
-
|
| 12 |
sonar.go.coverage.reportPaths=coverage.out
|
| 13 |
-
#sonar.coverageReportPaths=coverage.out
|
| 14 |
-
#onar.testExecutionReportPaths=report.json
|
| 15 |
sonar.go.tests.reportPaths=report.json
|
|
|
|
| 1 |
+
sonar.projectKey=zkevm-node
|
|
|
|
| 2 |
|
| 3 |
sonar.sources=.
|
| 4 |
sonar.exclusions=**/*_test.go
|
| 5 |
+
sonar.exclusions=**/mock_*.go
|
| 6 |
|
| 7 |
sonar.tests=.
|
| 8 |
sonar.test.inclusions=**/*_test.go
|
|
|
|
|
|
|
| 9 |
sonar.go.coverage.reportPaths=coverage.out
|
|
|
|
|
|
|
| 10 |
sonar.go.tests.reportPaths=report.json
|
|
@@ -1,11 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import "time"
|
| 4 |
-
|
| 5 |
-
// PendingBatch represents a batch pending to be executed
|
| 6 |
-
type PendingBatch struct {
|
| 7 |
-
BatchNumber uint64
|
| 8 |
-
BlobInnerNum uint64
|
| 9 |
-
CreatedAt time.Time
|
| 10 |
-
Processed bool
|
| 11 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -33,6 +33,7 @@
|
|
| 33 |
ForcedBlockHashL1 *common.Hash
|
| 34 |
SkipVerifyL1InfoRoot uint32
|
| 35 |
GlobalExitRoot common.Hash // GlobalExitRoot is not use for execute but use to OpenBatch (data on DB)
|
|
|
|
| 36 |
ClosingReason ClosingReason
|
| 37 |
}
|
| 38 |
|
|
@@ -68,6 +69,7 @@
|
|
| 68 |
ChainId: s.cfg.ChainID,
|
| 69 |
ForkId: request.ForkID,
|
| 70 |
ContextId: uuid.NewString(),
|
|
|
|
| 71 |
}
|
| 72 |
|
| 73 |
if request.SkipFirstChangeL2Block_V2 {
|
|
@@ -130,6 +132,7 @@
|
|
| 130 |
ForkId: forkId,
|
| 131 |
ContextId: uuid.NewString(),
|
| 132 |
SkipVerifyL1InfoRoot: skipVerifyL1InfoRoot,
|
|
|
|
| 133 |
}
|
| 134 |
|
| 135 |
if forcedBlockHashL1 != nil {
|
|
@@ -168,7 +171,7 @@
|
|
| 168 |
return nil, err
|
| 169 |
} else if processBatchResponse != nil && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 170 |
err = executor.ExecutorErr(processBatchResponse.Error)
|
| 171 |
-
s.eventLog.
|
| 172 |
}
|
| 173 |
|
| 174 |
return processBatchResponse, err
|
|
@@ -230,6 +233,7 @@
|
|
| 230 |
ContextId: uuid.NewString(),
|
| 231 |
SkipVerifyL1InfoRoot: processingCtx.SkipVerifyL1InfoRoot,
|
| 232 |
L1InfoRoot: processingCtx.L1InfoRoot.Bytes(),
|
|
|
|
| 233 |
}
|
| 234 |
|
| 235 |
if processingCtx.ForcedBlockHashL1 != nil {
|
|
@@ -299,12 +303,12 @@
|
|
| 299 |
log.Errorf("error executor ProcessBatchV2: %s", err.Error())
|
| 300 |
log.Errorf("error executor ProcessBatchV2 response: %v", batchResponse)
|
| 301 |
} else {
|
| 302 |
-
batchResponseToString :=
|
| 303 |
if batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 304 |
err = executor.ExecutorErr(batchResponse.Error)
|
| 305 |
log.Warnf("executor batch %d response, executor error: %v", newBatchNum, err)
|
| 306 |
log.Warn(batchResponseToString)
|
| 307 |
-
s.eventLog.
|
| 308 |
} else if batchResponse.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR && executor.IsROMOutOfCountersError(batchResponse.ErrorRom) {
|
| 309 |
err = executor.RomErr(batchResponse.ErrorRom)
|
| 310 |
log.Warnf("executor batch %d response, ROM OOC, error: %v", newBatchNum, err)
|
|
@@ -321,32 +325,32 @@
|
|
| 321 |
return batchResponse, err
|
| 322 |
}
|
| 323 |
|
| 324 |
-
func
|
| 325 |
batchResponseLog := "executor batch %d response, Time: %v, NewStateRoot: %v, NewAccInputHash: %v, NewLocalExitRoot: %v, NewBatchNumber: %v, GasUsed: %v, FlushId: %v, StoredFlushId: %v, ProverId:%v, ForkId:%v, Error: %v\n"
|
| 326 |
batchResponseLog = fmt.Sprintf(batchResponseLog, batchNum, executionTime, hex.EncodeToHex(batchResponse.NewStateRoot), hex.EncodeToHex(batchResponse.NewAccInputHash), hex.EncodeToHex(batchResponse.NewLocalExitRoot),
|
| 327 |
batchResponse.NewBatchNum, batchResponse.GasUsed, batchResponse.FlushId, batchResponse.StoredFlushId, batchResponse.ProverId, batchResponse.ForkId, batchResponse.Error)
|
| 328 |
|
| 329 |
for blockIndex, block := range batchResponse.BlockResponses {
|
| 330 |
prefix := " " + fmt.Sprintf("block[%v]: ", blockIndex)
|
| 331 |
-
batchResponseLog +=
|
| 332 |
}
|
| 333 |
|
| 334 |
return batchResponseLog
|
| 335 |
}
|
| 336 |
-
func
|
| 337 |
blockResponseLog := prefix + "ParentHash: %v, Coinbase: %v, GasLimit: %v, BlockNumber: %v, Timestamp: %v, GlobalExitRoot: %v, BlockHashL1: %v, GasUsed: %v, BlockInfoRoot: %v, BlockHash: %v\n"
|
| 338 |
blockResponseLog = fmt.Sprintf(blockResponseLog, common.BytesToHash(blockResponse.ParentHash), blockResponse.Coinbase, blockResponse.GasLimit, blockResponse.BlockNumber, blockResponse.Timestamp,
|
| 339 |
common.BytesToHash(blockResponse.Ger), common.BytesToHash(blockResponse.BlockHashL1), blockResponse.GasUsed, common.BytesToHash(blockResponse.BlockInfoRoot), common.BytesToHash(blockResponse.BlockHash))
|
| 340 |
|
| 341 |
for txIndex, tx := range blockResponse.Responses {
|
| 342 |
prefix := " " + fmt.Sprintf("tx[%v]: ", txIndex)
|
| 343 |
-
blockResponseLog +=
|
| 344 |
}
|
| 345 |
|
| 346 |
return blockResponseLog
|
| 347 |
}
|
| 348 |
|
| 349 |
-
func
|
| 350 |
txResponseLog := prefix + "TxHash: %v, TxHashL2: %v, Type: %v, StateRoot:%v, GasUsed: %v, GasLeft: %v, GasRefund: %v, Error: %v\n"
|
| 351 |
txResponseLog = fmt.Sprintf(txResponseLog, common.BytesToHash(txResponse.TxHash), common.BytesToHash(txResponse.TxHashL2), txResponse.Type,
|
| 352 |
common.BytesToHash(txResponse.StateRoot), txResponse.GasUsed, txResponse.GasLeft, txResponse.GasRefunded, txResponse.Error)
|
|
@@ -416,14 +420,3 @@
|
|
| 416 |
ClosingReason: processingCtx.ClosingReason,
|
| 417 |
}, dbTx)
|
| 418 |
}
|
| 419 |
-
|
| 420 |
-
// BuildChangeL2Block returns a changeL2Block tx to use in the BatchL2Data
|
| 421 |
-
func (p *State) BuildChangeL2Block(deltaTimestamp uint32, l1InfoTreeIndex uint32) []byte {
|
| 422 |
-
l2block := ChangeL2BlockHeader{
|
| 423 |
-
DeltaTimestamp: deltaTimestamp,
|
| 424 |
-
IndexL1InfoTree: l1InfoTreeIndex,
|
| 425 |
-
}
|
| 426 |
-
var data []byte
|
| 427 |
-
data = l2block.Encode(data)
|
| 428 |
-
return data
|
| 429 |
-
}
|
|
|
|
| 33 |
ForcedBlockHashL1 *common.Hash
|
| 34 |
SkipVerifyL1InfoRoot uint32
|
| 35 |
GlobalExitRoot common.Hash // GlobalExitRoot is not use for execute but use to OpenBatch (data on DB)
|
| 36 |
+
ExecutionMode uint64
|
| 37 |
ClosingReason ClosingReason
|
| 38 |
}
|
| 39 |
|
|
|
|
| 69 |
ChainId: s.cfg.ChainID,
|
| 70 |
ForkId: request.ForkID,
|
| 71 |
ContextId: uuid.NewString(),
|
| 72 |
+
ExecutionMode: request.ExecutionMode,
|
| 73 |
}
|
| 74 |
|
| 75 |
if request.SkipFirstChangeL2Block_V2 {
|
|
|
|
| 132 |
ForkId: forkId,
|
| 133 |
ContextId: uuid.NewString(),
|
| 134 |
SkipVerifyL1InfoRoot: skipVerifyL1InfoRoot,
|
| 135 |
+
ExecutionMode: executor.ExecutionMode1,
|
| 136 |
}
|
| 137 |
|
| 138 |
if forcedBlockHashL1 != nil {
|
|
|
|
| 171 |
return nil, err
|
| 172 |
} else if processBatchResponse != nil && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 173 |
err = executor.ExecutorErr(processBatchResponse.Error)
|
| 174 |
+
s.eventLog.LogExecutorErrorV2(ctx, processBatchResponse.Error, processBatchRequest)
|
| 175 |
}
|
| 176 |
|
| 177 |
return processBatchResponse, err
|
|
|
|
| 233 |
ContextId: uuid.NewString(),
|
| 234 |
SkipVerifyL1InfoRoot: processingCtx.SkipVerifyL1InfoRoot,
|
| 235 |
L1InfoRoot: processingCtx.L1InfoRoot.Bytes(),
|
| 236 |
+
ExecutionMode: processingCtx.ExecutionMode,
|
| 237 |
}
|
| 238 |
|
| 239 |
if processingCtx.ForcedBlockHashL1 != nil {
|
|
|
|
| 303 |
log.Errorf("error executor ProcessBatchV2: %s", err.Error())
|
| 304 |
log.Errorf("error executor ProcessBatchV2 response: %v", batchResponse)
|
| 305 |
} else {
|
| 306 |
+
batchResponseToString := processBatchResponseToString(newBatchNum, batchResponse, elapsed)
|
| 307 |
if batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 308 |
err = executor.ExecutorErr(batchResponse.Error)
|
| 309 |
log.Warnf("executor batch %d response, executor error: %v", newBatchNum, err)
|
| 310 |
log.Warn(batchResponseToString)
|
| 311 |
+
s.eventLog.LogExecutorErrorV2(ctx, batchResponse.Error, batchRequest)
|
| 312 |
} else if batchResponse.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR && executor.IsROMOutOfCountersError(batchResponse.ErrorRom) {
|
| 313 |
err = executor.RomErr(batchResponse.ErrorRom)
|
| 314 |
log.Warnf("executor batch %d response, ROM OOC, error: %v", newBatchNum, err)
|
|
|
|
| 325 |
return batchResponse, err
|
| 326 |
}
|
| 327 |
|
| 328 |
+
func processBatchResponseToString(batchNum uint64, batchResponse *executor.ProcessBatchResponseV2, executionTime time.Duration) string {
|
| 329 |
batchResponseLog := "executor batch %d response, Time: %v, NewStateRoot: %v, NewAccInputHash: %v, NewLocalExitRoot: %v, NewBatchNumber: %v, GasUsed: %v, FlushId: %v, StoredFlushId: %v, ProverId:%v, ForkId:%v, Error: %v\n"
|
| 330 |
batchResponseLog = fmt.Sprintf(batchResponseLog, batchNum, executionTime, hex.EncodeToHex(batchResponse.NewStateRoot), hex.EncodeToHex(batchResponse.NewAccInputHash), hex.EncodeToHex(batchResponse.NewLocalExitRoot),
|
| 331 |
batchResponse.NewBatchNum, batchResponse.GasUsed, batchResponse.FlushId, batchResponse.StoredFlushId, batchResponse.ProverId, batchResponse.ForkId, batchResponse.Error)
|
| 332 |
|
| 333 |
for blockIndex, block := range batchResponse.BlockResponses {
|
| 334 |
prefix := " " + fmt.Sprintf("block[%v]: ", blockIndex)
|
| 335 |
+
batchResponseLog += blockResponseToString(block, prefix)
|
| 336 |
}
|
| 337 |
|
| 338 |
return batchResponseLog
|
| 339 |
}
|
| 340 |
+
func blockResponseToString(blockResponse *executor.ProcessBlockResponseV2, prefix string) string {
|
| 341 |
blockResponseLog := prefix + "ParentHash: %v, Coinbase: %v, GasLimit: %v, BlockNumber: %v, Timestamp: %v, GlobalExitRoot: %v, BlockHashL1: %v, GasUsed: %v, BlockInfoRoot: %v, BlockHash: %v\n"
|
| 342 |
blockResponseLog = fmt.Sprintf(blockResponseLog, common.BytesToHash(blockResponse.ParentHash), blockResponse.Coinbase, blockResponse.GasLimit, blockResponse.BlockNumber, blockResponse.Timestamp,
|
| 343 |
common.BytesToHash(blockResponse.Ger), common.BytesToHash(blockResponse.BlockHashL1), blockResponse.GasUsed, common.BytesToHash(blockResponse.BlockInfoRoot), common.BytesToHash(blockResponse.BlockHash))
|
| 344 |
|
| 345 |
for txIndex, tx := range blockResponse.Responses {
|
| 346 |
prefix := " " + fmt.Sprintf("tx[%v]: ", txIndex)
|
| 347 |
+
blockResponseLog += transactionResponseToString(tx, prefix)
|
| 348 |
}
|
| 349 |
|
| 350 |
return blockResponseLog
|
| 351 |
}
|
| 352 |
|
| 353 |
+
func transactionResponseToString(txResponse *executor.ProcessTransactionResponseV2, prefix string) string {
|
| 354 |
txResponseLog := prefix + "TxHash: %v, TxHashL2: %v, Type: %v, StateRoot:%v, GasUsed: %v, GasLeft: %v, GasRefund: %v, Error: %v\n"
|
| 355 |
txResponseLog = fmt.Sprintf(txResponseLog, common.BytesToHash(txResponse.TxHash), common.BytesToHash(txResponse.TxHashL2), txResponse.Type,
|
| 356 |
common.BytesToHash(txResponse.StateRoot), txResponse.GasUsed, txResponse.GasLeft, txResponse.GasRefunded, txResponse.Error)
|
|
|
|
| 420 |
ClosingReason: processingCtx.ClosingReason,
|
| 421 |
}, dbTx)
|
| 422 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -44,7 +44,7 @@
|
|
| 44 |
ctx := context.Background()
|
| 45 |
mockStorage := mocks.NewStorageMock(t)
|
| 46 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 47 |
-
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil
|
| 48 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 49 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 50 |
require.NoError(t, err)
|
|
@@ -122,7 +122,7 @@
|
|
| 122 |
ctx := context.Background()
|
| 123 |
mockStorage := mocks.NewStorageMock(t)
|
| 124 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 125 |
-
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil
|
| 126 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 127 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 128 |
require.NoError(t, err)
|
|
|
|
| 44 |
ctx := context.Background()
|
| 45 |
mockStorage := mocks.NewStorageMock(t)
|
| 46 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 47 |
+
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil)
|
| 48 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 49 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 50 |
require.NoError(t, err)
|
|
|
|
| 122 |
ctx := context.Background()
|
| 123 |
mockStorage := mocks.NewStorageMock(t)
|
| 124 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 125 |
+
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil)
|
| 126 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 127 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 128 |
require.NoError(t, err)
|
|
@@ -1,137 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
"time"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/state/metrics"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 12 |
-
"github.com/google/uuid"
|
| 13 |
-
)
|
| 14 |
-
|
| 15 |
-
// ProcessBatchV3 processes a batch for forkID >= FEIJOA
|
| 16 |
-
func (s *State) ProcessBatchV3(ctx context.Context, request ProcessRequest, updateMerkleTree bool) (*ProcessBatchResponse, error) {
|
| 17 |
-
updateMT := uint32(cFalse)
|
| 18 |
-
if updateMerkleTree {
|
| 19 |
-
updateMT = cTrue
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
l1InfoTreeData := make(map[uint32]*executor.L1DataV3)
|
| 23 |
-
|
| 24 |
-
for k, v := range request.L1InfoTreeData_V3 {
|
| 25 |
-
l1InfoTreeData[k] = &executor.L1DataV3{
|
| 26 |
-
GlobalExitRoot: v.GlobalExitRoot.Bytes(),
|
| 27 |
-
BlockHashL1: v.BlockHashL1.Bytes(),
|
| 28 |
-
MinTimestamp: v.MinTimestamp,
|
| 29 |
-
SmtProofPreviousIndex: v.SmtProofPreviousIndex,
|
| 30 |
-
InitialHistoricRoot: v.InitialHistoricRoot.Bytes(),
|
| 31 |
-
}
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
-
// Create Batch
|
| 35 |
-
var processBatchRequest = &executor.ProcessBatchRequestV3{
|
| 36 |
-
OldStateRoot: request.OldStateRoot.Bytes(),
|
| 37 |
-
OldAccInputHash: request.OldAccInputHash.Bytes(),
|
| 38 |
-
PreviousL1InfoTreeRoot: request.PreviousL1InfoTreeRoot_V3.Bytes(),
|
| 39 |
-
PreviousL1InfoTreeIndex: request.PreviousL1InfoTreeIndex_V3,
|
| 40 |
-
ChainId: s.cfg.ChainID,
|
| 41 |
-
ForkId: request.ForkID,
|
| 42 |
-
BatchL2Data: request.Transactions,
|
| 43 |
-
Coinbase: request.Coinbase.String(),
|
| 44 |
-
UpdateMerkleTree: updateMT,
|
| 45 |
-
L1InfoTreeData: l1InfoTreeData,
|
| 46 |
-
ContextId: uuid.NewString(),
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
if request.SkipFirstChangeL2Block_V2 {
|
| 50 |
-
processBatchRequest.SkipFirstChangeL2Block = cTrue
|
| 51 |
-
}
|
| 52 |
-
|
| 53 |
-
if request.SkipWriteBlockInfoRoot_V2 {
|
| 54 |
-
processBatchRequest.SkipWriteBlockInfoRoot = cTrue
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
res, err := s.sendBatchRequestToExecutorV3(ctx, processBatchRequest, request.Caller)
|
| 58 |
-
if err != nil {
|
| 59 |
-
return nil, err
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
var result *ProcessBatchResponse
|
| 63 |
-
result, err = s.convertToProcessBatchResponseV3(res)
|
| 64 |
-
if err != nil {
|
| 65 |
-
return nil, err
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
return result, nil
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
func (s *State) sendBatchRequestToExecutorV3(ctx context.Context, batchRequest *executor.ProcessBatchRequestV3, caller metrics.CallerLabel) (*executor.ProcessBatchResponseV3, error) {
|
| 72 |
-
if s.executorClient == nil {
|
| 73 |
-
return nil, ErrExecutorNil
|
| 74 |
-
}
|
| 75 |
-
|
| 76 |
-
l1DataStr := ""
|
| 77 |
-
for i, l1Data := range batchRequest.L1InfoTreeData {
|
| 78 |
-
l1DataStr += fmt.Sprintf("[%d]{GlobalExitRoot: %v, BlockHashL1: %v, MinTimestamp: %v},", i, hex.EncodeToHex(l1Data.GlobalExitRoot), hex.EncodeToHex(l1Data.BlockHashL1), l1Data.MinTimestamp)
|
| 79 |
-
}
|
| 80 |
-
if l1DataStr != "" {
|
| 81 |
-
l1DataStr = l1DataStr[:len(l1DataStr)-1]
|
| 82 |
-
}
|
| 83 |
-
|
| 84 |
-
// Log the batch request
|
| 85 |
-
batchRequestLog := "OldStateRoot: %v, OldAccInputHash: %v, PreviousL1InfoTreeRoot: %v, PreviousL1InfoTreeIndex: %v, ChainId: %v, ForkId: %v, BatchL2Data: %v, Coinbase: %v, UpdateMerkleTree: %v, L1InfoTreeData: %+v, ContextId: %v, SkipFirstChangeL2Block: %v, SkipWriteBlockInfoRoot: %v"
|
| 86 |
-
batchRequestLog = fmt.Sprintf(batchRequestLog, hex.EncodeToHex(batchRequest.OldStateRoot), hex.EncodeToHex(batchRequest.OldAccInputHash), hex.EncodeToHex(batchRequest.PreviousL1InfoTreeRoot), batchRequest.PreviousL1InfoTreeIndex, batchRequest.ChainId, batchRequest.ForkId, len(batchRequest.BatchL2Data), batchRequest.Coinbase, batchRequest.UpdateMerkleTree, l1DataStr, batchRequest.ContextId, batchRequest.SkipFirstChangeL2Block, batchRequest.SkipWriteBlockInfoRoot)
|
| 87 |
-
|
| 88 |
-
log.Debugf("executor batch request, %s", batchRequestLog)
|
| 89 |
-
|
| 90 |
-
now := time.Now()
|
| 91 |
-
batchResponse, err := s.executorClient.ProcessBatchV3(ctx, batchRequest)
|
| 92 |
-
elapsed := time.Since(now)
|
| 93 |
-
|
| 94 |
-
// workarroundDuplicatedBlock(res)
|
| 95 |
-
if caller != metrics.DiscardCallerLabel {
|
| 96 |
-
metrics.ExecutorProcessingTime(string(caller), elapsed)
|
| 97 |
-
}
|
| 98 |
-
|
| 99 |
-
if err != nil {
|
| 100 |
-
log.Errorf("error executor ProcessBatchV3: %v", err)
|
| 101 |
-
log.Errorf("error executor ProcessBatchV3: %s", err.Error())
|
| 102 |
-
log.Errorf("error executor ProcessBatchV3 response: %v", batchResponse)
|
| 103 |
-
} else {
|
| 104 |
-
batchResponseToString := processBatchResponseV3ToString(batchResponse, elapsed)
|
| 105 |
-
if batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 106 |
-
err = executor.ExecutorErr(batchResponse.Error)
|
| 107 |
-
log.Warnf("executor batch response, executor error: %v", err)
|
| 108 |
-
log.Warn(batchResponseToString)
|
| 109 |
-
s.eventLog.LogExecutorError(ctx, batchResponse.Error, batchRequest)
|
| 110 |
-
} else if batchResponse.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR && executor.IsROMOutOfCountersError(batchResponse.ErrorRom) {
|
| 111 |
-
err = executor.RomErr(batchResponse.ErrorRom)
|
| 112 |
-
log.Warnf("executor batch response, ROM OOC, error: %v", err)
|
| 113 |
-
log.Warn(batchResponseToString)
|
| 114 |
-
} else if batchResponse.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR {
|
| 115 |
-
err = executor.RomErr(batchResponse.ErrorRom)
|
| 116 |
-
log.Warnf("executor batch response, ROM error: %v", err)
|
| 117 |
-
log.Warn(batchResponseToString)
|
| 118 |
-
} else {
|
| 119 |
-
log.Debug(batchResponseToString)
|
| 120 |
-
}
|
| 121 |
-
}
|
| 122 |
-
|
| 123 |
-
return batchResponse, err
|
| 124 |
-
}
|
| 125 |
-
|
| 126 |
-
func processBatchResponseV3ToString(batchResponse *executor.ProcessBatchResponseV3, executionTime time.Duration) string {
|
| 127 |
-
batchResponseLog := "executor batch response, Time: %v, NewStateRoot: %v, NewAccInputHash: %v, NewLocalExitRoot: %v, GasUsed: %v, FlushId: %v, StoredFlushId: %v, ProverId:%v, ForkId:%v, Error: %v\n"
|
| 128 |
-
batchResponseLog = fmt.Sprintf(batchResponseLog, executionTime, hex.EncodeToHex(batchResponse.NewStateRoot), hex.EncodeToHex(batchResponse.NewAccInputHash), hex.EncodeToHex(batchResponse.NewLocalExitRoot),
|
| 129 |
-
batchResponse.GasUsed, batchResponse.FlushId, batchResponse.StoredFlushId, batchResponse.ProverId, batchResponse.ForkId, batchResponse.Error)
|
| 130 |
-
|
| 131 |
-
for blockIndex, block := range batchResponse.BlockResponses {
|
| 132 |
-
prefix := " " + fmt.Sprintf("block[%v]: ", blockIndex)
|
| 133 |
-
batchResponseLog += blockResponseV2ToString(block, prefix)
|
| 134 |
-
}
|
| 135 |
-
|
| 136 |
-
return batchResponseLog
|
| 137 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,101 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
"time"
|
| 7 |
-
|
| 8 |
-
"github.com/ethereum/go-ethereum/common"
|
| 9 |
-
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
| 10 |
-
"github.com/jackc/pgx/v4"
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
// BlobType is the type of the blob type
|
| 14 |
-
type BlobType uint8
|
| 15 |
-
|
| 16 |
-
const (
|
| 17 |
-
// TypeCallData The data is stored on call data directly
|
| 18 |
-
TypeCallData BlobType = 0
|
| 19 |
-
// TypeBlobTransaction The data is stored on a blob
|
| 20 |
-
TypeBlobTransaction BlobType = 1
|
| 21 |
-
// TypeForcedBlob The data is a forced Blob
|
| 22 |
-
TypeForcedBlob BlobType = 2
|
| 23 |
-
)
|
| 24 |
-
|
| 25 |
-
func (b BlobType) String() string {
|
| 26 |
-
switch b {
|
| 27 |
-
case TypeCallData:
|
| 28 |
-
return "call_data"
|
| 29 |
-
case TypeBlobTransaction:
|
| 30 |
-
return "blob"
|
| 31 |
-
case TypeForcedBlob:
|
| 32 |
-
return "forced"
|
| 33 |
-
default:
|
| 34 |
-
return "Unknown"
|
| 35 |
-
}
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
// BlobBlobTypeParams is the data for a SequenceBlob stored as a Blob
|
| 39 |
-
type BlobBlobTypeParams struct {
|
| 40 |
-
BlobIndex uint64
|
| 41 |
-
Z []byte
|
| 42 |
-
Y []byte
|
| 43 |
-
Commitment kzg4844.Commitment
|
| 44 |
-
Proof kzg4844.Proof
|
| 45 |
-
}
|
| 46 |
-
|
| 47 |
-
// BlobInner struct
|
| 48 |
-
type BlobInner struct {
|
| 49 |
-
BlobSequenceIndex uint64 // Index of the blobSequence in DB (is a internal number)
|
| 50 |
-
BlobInnerNum uint64 // Incremental value, starts from 1
|
| 51 |
-
Type BlobType // Type of the blob
|
| 52 |
-
MaxSequenceTimestamp time.Time // it comes from SequenceBlobs call to contract
|
| 53 |
-
ZkGasLimit uint64 // it comes from SequenceBlobs call to contract
|
| 54 |
-
L1InfoLeafIndex uint32 // it comes from SequenceBlobs call to contract
|
| 55 |
-
L1InfoTreeRoot common.Hash // obtained from the L1InfoTree
|
| 56 |
-
BlobDataHash common.Hash // Hash of the data
|
| 57 |
-
BlobBlobTypeParams *BlobBlobTypeParams // Field only valid if BlobType == BlobTransaction
|
| 58 |
-
//HowManyBatches uint64 // Number of batches in the blob
|
| 59 |
-
//FirstBatchNumber uint64 // First batch number of the blob
|
| 60 |
-
//LastBatchNumber uint64 // Last batch number of the blob
|
| 61 |
-
// We don't need blockNumber because is in BlobSequence
|
| 62 |
-
//BlockNumber uint64
|
| 63 |
-
//PreviousL1InfoTreeIndex uint32 // ?? we need that?
|
| 64 |
-
//PreviousL1InfoTreeRoot common.Hash // ?? we need that?
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
func (b *BlobInner) String() string {
|
| 68 |
-
res := fmt.Sprintf("BlobInner{BlobSequenceIndex:%d, BlobInnerNum:%d, Type:%s, MaxSequenceTimestamp:%s, ZkGasLimit:%d, L1InfoLeafIndex:%d, L1InfoTreeRoot:%s, BlobDataHash:%s",
|
| 69 |
-
b.BlobSequenceIndex, b.BlobInnerNum, b.Type.String(), b.MaxSequenceTimestamp.String(), b.ZkGasLimit, b.L1InfoLeafIndex, b.L1InfoTreeRoot.String(), b.BlobDataHash.String())
|
| 70 |
-
if b.BlobBlobTypeParams != nil {
|
| 71 |
-
res += ", BlobBlobTypeParams: " + b.BlobBlobTypeParams.String()
|
| 72 |
-
}
|
| 73 |
-
res += "}"
|
| 74 |
-
return res
|
| 75 |
-
}
|
| 76 |
-
|
| 77 |
-
func (b *BlobBlobTypeParams) String() string {
|
| 78 |
-
return "BlobBlobTypeParams{" +
|
| 79 |
-
"BlobIndex: " + fmt.Sprintf("%d", b.BlobIndex) +
|
| 80 |
-
", Z: " + common.Bytes2Hex(b.Z) +
|
| 81 |
-
", Y: " + common.Bytes2Hex(b.Y) +
|
| 82 |
-
", Commitment: " + common.Bytes2Hex(b.Commitment[:]) +
|
| 83 |
-
", Proof: " + common.Bytes2Hex(b.Proof[:]) +
|
| 84 |
-
"}"
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
// IsEqual compares two BlobInner
|
| 88 |
-
func (b *BlobInner) IsEqual(other *BlobInner) bool {
|
| 89 |
-
if b == nil && other == nil {
|
| 90 |
-
return true
|
| 91 |
-
}
|
| 92 |
-
if b == nil || other == nil {
|
| 93 |
-
return false
|
| 94 |
-
}
|
| 95 |
-
return b.String() == other.String()
|
| 96 |
-
}
|
| 97 |
-
|
| 98 |
-
// AddBlobInner adds a blob inner to the database, currently is just a call to storage
|
| 99 |
-
func (s *State) AddBlobInner(ctx context.Context, blobInner *BlobInner, dbTx pgx.Tx) error {
|
| 100 |
-
return s.storage.AddBlobInner(ctx, blobInner, dbTx)
|
| 101 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,18 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
|
| 6 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 7 |
-
)
|
| 8 |
-
|
| 9 |
-
// ProcessBlobInner processes a blobInner and returns the splitted batches
|
| 10 |
-
func (s *State) ProcessBlobInner(ctx context.Context, request ProcessBlobInnerProcessRequest, data []byte) (*ProcessBlobInnerResponse, error) {
|
| 11 |
-
requestExecutor := convertBlobInnerProcessRequestToExecutor(request, data)
|
| 12 |
-
processResponse, err := s.executorClient.ProcessBlobInnerV3(ctx, requestExecutor)
|
| 13 |
-
if err != nil {
|
| 14 |
-
log.Errorf("Error processing blobInner: %v", err)
|
| 15 |
-
return nil, err
|
| 16 |
-
}
|
| 17 |
-
return newProcessBlobInnerProcessResponse(processResponse), nil
|
| 18 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,81 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 5 |
-
"github.com/ethereum/go-ethereum/common"
|
| 6 |
-
)
|
| 7 |
-
|
| 8 |
-
// ProcessBlobInnerProcessRequest is the request to process a blob
|
| 9 |
-
// you must use the builder to create the request
|
| 10 |
-
type ProcessBlobInnerProcessRequest struct {
|
| 11 |
-
oldBlobStateRoot common.Hash
|
| 12 |
-
oldBlobAccInputHash common.Hash
|
| 13 |
-
oldNumBlob uint64
|
| 14 |
-
oldStateRoot common.Hash
|
| 15 |
-
forkId uint64
|
| 16 |
-
lastL1InfoTreeIndex uint32
|
| 17 |
-
lastL1InfoTreeRoot common.Hash
|
| 18 |
-
timestampLimit uint64
|
| 19 |
-
coinbase common.Address
|
| 20 |
-
zkGasLimit uint64
|
| 21 |
-
blobType BlobType
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
// NewProcessBlobInnerProcessRequest creates a new ProcessBlobInnerProcessRequest
|
| 25 |
-
func NewProcessBlobInnerProcessRequest(forkid uint64, blob *BlobInner,
|
| 26 |
-
previousSequence *BlobSequence,
|
| 27 |
-
currentSequence BlobSequence) (*ProcessBlobInnerProcessRequest, error) {
|
| 28 |
-
res := &ProcessBlobInnerProcessRequest{
|
| 29 |
-
forkId: forkid,
|
| 30 |
-
blobType: blob.Type,
|
| 31 |
-
oldBlobStateRoot: ZeroHash, // Is always zero!
|
| 32 |
-
}
|
| 33 |
-
if previousSequence == nil {
|
| 34 |
-
res.setAsFirstBlob()
|
| 35 |
-
} else {
|
| 36 |
-
res.setPreviousSequence(*previousSequence)
|
| 37 |
-
}
|
| 38 |
-
res.setBlob(blob)
|
| 39 |
-
res.setCurrentSequence(currentSequence)
|
| 40 |
-
return res, nil
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
func (p *ProcessBlobInnerProcessRequest) setAsFirstBlob() {
|
| 44 |
-
p.oldBlobStateRoot = ZeroHash
|
| 45 |
-
p.oldBlobAccInputHash = ZeroHash
|
| 46 |
-
p.oldNumBlob = 0
|
| 47 |
-
p.oldStateRoot = ZeroHash
|
| 48 |
-
}
|
| 49 |
-
|
| 50 |
-
func (p *ProcessBlobInnerProcessRequest) setCurrentSequence(seq BlobSequence) {
|
| 51 |
-
p.coinbase = seq.L2Coinbase
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
func (p *ProcessBlobInnerProcessRequest) setPreviousSequence(previousSequence BlobSequence) {
|
| 55 |
-
p.oldBlobAccInputHash = previousSequence.FinalAccInputHash
|
| 56 |
-
p.oldNumBlob = previousSequence.LastBlobSequenced
|
| 57 |
-
}
|
| 58 |
-
|
| 59 |
-
func (p *ProcessBlobInnerProcessRequest) setBlob(blob *BlobInner) {
|
| 60 |
-
p.lastL1InfoTreeIndex = blob.L1InfoLeafIndex
|
| 61 |
-
p.lastL1InfoTreeRoot = blob.L1InfoTreeRoot
|
| 62 |
-
p.timestampLimit = uint64(blob.MaxSequenceTimestamp.Unix()) // Convert time.Time to uint64
|
| 63 |
-
p.zkGasLimit = blob.ZkGasLimit
|
| 64 |
-
}
|
| 65 |
-
|
| 66 |
-
func convertBlobInnerProcessRequestToExecutor(request ProcessBlobInnerProcessRequest, data []byte) *executor.ProcessBlobInnerRequestV3 {
|
| 67 |
-
return &executor.ProcessBlobInnerRequestV3{
|
| 68 |
-
OldBlobStateRoot: request.oldBlobStateRoot.Bytes(),
|
| 69 |
-
OldBlobAccInputHash: request.oldBlobAccInputHash.Bytes(),
|
| 70 |
-
OldNumBlob: request.oldNumBlob,
|
| 71 |
-
OldStateRoot: request.oldStateRoot.Bytes(),
|
| 72 |
-
ForkId: request.forkId,
|
| 73 |
-
LastL1InfoTreeIndex: request.lastL1InfoTreeIndex,
|
| 74 |
-
LastL1InfoTreeRoot: request.lastL1InfoTreeRoot.Bytes(),
|
| 75 |
-
TimestampLimit: request.timestampLimit,
|
| 76 |
-
Coinbase: request.coinbase.String(),
|
| 77 |
-
ZkGasLimit: request.zkGasLimit,
|
| 78 |
-
BlobType: uint32(request.blobType),
|
| 79 |
-
BlobData: data,
|
| 80 |
-
}
|
| 81 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,114 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"fmt"
|
| 5 |
-
|
| 6 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 8 |
-
"github.com/ethereum/go-ethereum/common"
|
| 9 |
-
"github.com/ethereum/go-ethereum/crypto"
|
| 10 |
-
)
|
| 11 |
-
|
| 12 |
-
// ProcessBlobInnerResponse is the response of the process of a blob
|
| 13 |
-
// the fields are private, so you need the function to access the data
|
| 14 |
-
// To get the outcome of the execution you must use GetSuccesfulData() it will return a nil if the execution was not successful
|
| 15 |
-
// This is for forcing by interface don't access to results fields is it have an error
|
| 16 |
-
type ProcessBlobInnerResponse struct {
|
| 17 |
-
succesfulData ProcessBlobInnerResponseSuccesful // Here is the outcome of the execution
|
| 18 |
-
isInvalid bool // Is a variable of the ROM
|
| 19 |
-
generalError error
|
| 20 |
-
romBlobError error
|
| 21 |
-
executorVersion string // Version of the executor e.g. "v7.0.0"
|
| 22 |
-
errorDebugLog string // This is debug.ErrorLog that is a debug string with context data of error
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
// ProcessBlobInnerResponseSuccesful is the data after a successful call to ProcessBlobInner
|
| 26 |
-
type ProcessBlobInnerResponseSuccesful struct {
|
| 27 |
-
newBlobStateRoot common.Hash
|
| 28 |
-
newBlobAccInputHash common.Hash
|
| 29 |
-
newNumBlob uint64
|
| 30 |
-
finalAccBatchHashData common.Hash
|
| 31 |
-
batchData [][]byte
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
-
func (p *ProcessBlobInnerResponseSuccesful) String() string {
|
| 35 |
-
res := fmt.Sprintf("newBlobStateRoot: %s newBlobAccInputHash:%s newNumBlob:%d\n", p.newBlobStateRoot.String(), p.newBlobAccInputHash.String(), p.newNumBlob)
|
| 36 |
-
res += fmt.Sprintf("finalAccBatchHashData: %s\n", p.finalAccBatchHashData.String())
|
| 37 |
-
res += fmt.Sprintf("HowManyBatches: %d\n", p.HowManyBatches())
|
| 38 |
-
for i := 0; i < p.HowManyBatches(); i++ {
|
| 39 |
-
res += fmt.Sprintf(" Batch %d: Hash:%s\n", i, p.GetBatchHash(i).String())
|
| 40 |
-
}
|
| 41 |
-
return res
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
func (p *ProcessBlobInnerResponse) String() string {
|
| 45 |
-
res := fmt.Sprintf("isInvalid: %t\n", p.isInvalid)
|
| 46 |
-
if p.generalError != nil {
|
| 47 |
-
res += fmt.Sprintf("generalError: %s\n", p.generalError.Error())
|
| 48 |
-
}
|
| 49 |
-
if p.romBlobError != nil {
|
| 50 |
-
res += fmt.Sprintf("romBlobError: %s\n", p.romBlobError.Error())
|
| 51 |
-
}
|
| 52 |
-
if p.IsSuccessfulExecution() {
|
| 53 |
-
res += p.succesfulData.String()
|
| 54 |
-
}
|
| 55 |
-
return res
|
| 56 |
-
}
|
| 57 |
-
|
| 58 |
-
// GetUnifiedError returns the combinations of errors of the execution
|
| 59 |
-
func (p *ProcessBlobInnerResponse) GetUnifiedError() error {
|
| 60 |
-
if p.IsSuccessfulExecution() {
|
| 61 |
-
return nil
|
| 62 |
-
}
|
| 63 |
-
return fmt.Errorf("ProcessBlobInnerV3 fails:version:%s isInvalid: %t general:%w romBlob:%w errorLog:%s",
|
| 64 |
-
p.executorVersion, p.isInvalid, p.generalError, p.romBlobError, p.errorDebugLog)
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
// IsSuccessfulExecution returns true if the execution was successful
|
| 68 |
-
func (p *ProcessBlobInnerResponse) IsSuccessfulExecution() bool {
|
| 69 |
-
return !p.isInvalid && p.generalError == nil && p.romBlobError == nil
|
| 70 |
-
}
|
| 71 |
-
|
| 72 |
-
// GetSuccesfulData returns the outcome data of the execution
|
| 73 |
-
func (p *ProcessBlobInnerResponse) GetSuccesfulData() *ProcessBlobInnerResponseSuccesful {
|
| 74 |
-
if !p.IsSuccessfulExecution() {
|
| 75 |
-
log.Error("Trying to get successful data from a failed execution")
|
| 76 |
-
return nil
|
| 77 |
-
}
|
| 78 |
-
return &p.succesfulData
|
| 79 |
-
}
|
| 80 |
-
|
| 81 |
-
// HowManyBatches returns the number of batches
|
| 82 |
-
func (p *ProcessBlobInnerResponseSuccesful) HowManyBatches() int {
|
| 83 |
-
return len(p.batchData)
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
// GetBatchData returns the data of the batch
|
| 87 |
-
func (p *ProcessBlobInnerResponseSuccesful) GetBatchData(index int) []byte {
|
| 88 |
-
return p.batchData[index]
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
// GetBatchHash returns the hash of the batch data
|
| 92 |
-
func (p *ProcessBlobInnerResponseSuccesful) GetBatchHash(index int) common.Hash {
|
| 93 |
-
return crypto.Keccak256Hash(p.GetBatchData(index))
|
| 94 |
-
}
|
| 95 |
-
|
| 96 |
-
func newProcessBlobInnerProcessResponse(response *executor.ProcessBlobInnerResponseV3) *ProcessBlobInnerResponse {
|
| 97 |
-
res := &ProcessBlobInnerResponse{
|
| 98 |
-
succesfulData: ProcessBlobInnerResponseSuccesful{
|
| 99 |
-
newBlobStateRoot: common.BytesToHash(response.NewBlobStateRoot),
|
| 100 |
-
newBlobAccInputHash: common.BytesToHash(response.NewBlobAccInputHash),
|
| 101 |
-
newNumBlob: response.NewNumBlob,
|
| 102 |
-
finalAccBatchHashData: common.BytesToHash(response.FinalAccBatchHashData),
|
| 103 |
-
batchData: response.BatchData,
|
| 104 |
-
},
|
| 105 |
-
isInvalid: response.IsInvalid == cTrue,
|
| 106 |
-
generalError: executor.ExecutorErr(response.Error),
|
| 107 |
-
romBlobError: executor.RomBlobErr(response.ErrorRomBlob),
|
| 108 |
-
}
|
| 109 |
-
if response.Debug != nil {
|
| 110 |
-
res.executorVersion = response.Debug.Version
|
| 111 |
-
res.errorDebugLog = response.Debug.ErrorLog
|
| 112 |
-
}
|
| 113 |
-
return res
|
| 114 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,69 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
"fmt"
|
| 7 |
-
"time"
|
| 8 |
-
|
| 9 |
-
"github.com/ethereum/go-ethereum/common"
|
| 10 |
-
"github.com/jackc/pgx/v4"
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
var (
|
| 14 |
-
// ErrBlobSequenceIndex is returned when the blob sequence index is not correct
|
| 15 |
-
ErrBlobSequenceIndex = errors.New("blob sequence index is not correct")
|
| 16 |
-
// ErrBlobSequenceTime is returned when the blob sequence time is not correct
|
| 17 |
-
ErrBlobSequenceTime = errors.New("blob sequence time is not correct")
|
| 18 |
-
)
|
| 19 |
-
|
| 20 |
-
// BlobSequence represents a blob sequence.
|
| 21 |
-
type BlobSequence struct {
|
| 22 |
-
BlobSequenceIndex uint64
|
| 23 |
-
L2Coinbase common.Address
|
| 24 |
-
FinalAccInputHash common.Hash
|
| 25 |
-
FirstBlobSequenced uint64 // Is calculated from previous blob sequence
|
| 26 |
-
LastBlobSequenced uint64 // That comes from the event
|
| 27 |
-
CreateAt time.Time // time of the L1block
|
| 28 |
-
ReceivedAt time.Time // time when the blob sequence is received (typically Now())
|
| 29 |
-
BlockNumber uint64 // L1BlockNumber where appears this event
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
// AddBlobSequence adds a new blob sequence to the state.
|
| 33 |
-
// it override pgstorage.AddBlobSequence to add sanity checks
|
| 34 |
-
func (s *State) AddBlobSequence(ctx context.Context, blobSequence *BlobSequence, dbTx pgx.Tx) error {
|
| 35 |
-
err := s.sanityCheckAddBlobSequence(ctx, blobSequence, dbTx)
|
| 36 |
-
if err != nil {
|
| 37 |
-
return err
|
| 38 |
-
}
|
| 39 |
-
return s.storage.AddBlobSequence(ctx, blobSequence, dbTx)
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
func (s *State) sanityCheckAddBlobSequence(ctx context.Context, blobSequence *BlobSequence, dbTx pgx.Tx) error {
|
| 43 |
-
previousBlobSequence, err := s.GetLastBlobSequence(ctx, dbTx)
|
| 44 |
-
if err != nil {
|
| 45 |
-
return err
|
| 46 |
-
}
|
| 47 |
-
if previousBlobSequence == nil {
|
| 48 |
-
// Is the first one
|
| 49 |
-
if blobSequence.BlobSequenceIndex != 1 {
|
| 50 |
-
return fmt.Errorf("TThe firstBlobSequence index must be 1, not %d. Err: %w", blobSequence.BlobSequenceIndex, ErrBlobSequenceIndex)
|
| 51 |
-
}
|
| 52 |
-
return nil
|
| 53 |
-
}
|
| 54 |
-
// The index must be the previous index + 1
|
| 55 |
-
if previousBlobSequence.BlobSequenceIndex+1 != blobSequence.BlobSequenceIndex {
|
| 56 |
-
return fmt.Errorf("last_index_on_db:%d try_to_insert:%d. Err: %w",
|
| 57 |
-
previousBlobSequence.BlobSequenceIndex,
|
| 58 |
-
blobSequence.BlobSequenceIndex,
|
| 59 |
-
ErrBlobSequenceIndex)
|
| 60 |
-
}
|
| 61 |
-
// The new blob must be newer than the previous one
|
| 62 |
-
if previousBlobSequence.CreateAt.After(blobSequence.CreateAt) {
|
| 63 |
-
return fmt.Errorf("last_create_at_on_db:%d try_to_insert:%d. Err: %w",
|
| 64 |
-
previousBlobSequence.CreateAt.Unix(),
|
| 65 |
-
blobSequence.CreateAt.Unix(),
|
| 66 |
-
ErrBlobSequenceTime)
|
| 67 |
-
}
|
| 68 |
-
return nil
|
| 69 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -66,7 +66,6 @@
|
|
| 66 |
ForkID: batchResponse.ForkId,
|
| 67 |
InvalidBatch_V2: batchResponse.InvalidBatch != 0,
|
| 68 |
RomError_V2: executor.RomErr(batchResponse.ErrorRom),
|
| 69 |
-
OldStateRoot_V2: common.BytesToHash(batchResponse.OldStateRoot),
|
| 70 |
}, nil
|
| 71 |
}
|
| 72 |
|
|
|
|
| 66 |
ForkID: batchResponse.ForkId,
|
| 67 |
InvalidBatch_V2: batchResponse.InvalidBatch != 0,
|
| 68 |
RomError_V2: executor.RomErr(batchResponse.ErrorRom),
|
|
|
|
| 69 |
}, nil
|
| 70 |
}
|
| 71 |
|
|
@@ -1,79 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 5 |
-
"github.com/ethereum/go-ethereum/common"
|
| 6 |
-
)
|
| 7 |
-
|
| 8 |
-
// TestConvertToProcessBatchResponseV3 for test purposes
|
| 9 |
-
func (s *State) TestConvertToProcessBatchResponseV3(batchResponse *executor.ProcessBatchResponseV3) (*ProcessBatchResponse, error) {
|
| 10 |
-
return s.convertToProcessBatchResponseV3(batchResponse)
|
| 11 |
-
}
|
| 12 |
-
|
| 13 |
-
func (s *State) convertToProcessBatchResponseV3(batchResponse *executor.ProcessBatchResponseV3) (*ProcessBatchResponse, error) {
|
| 14 |
-
blockResponses, isRomLevelError, isRomOOCError, err := s.convertToProcessBlockResponseV2(batchResponse.BlockResponses)
|
| 15 |
-
if err != nil {
|
| 16 |
-
return nil, err
|
| 17 |
-
}
|
| 18 |
-
isRomOOCError = isRomOOCError || executor.IsROMOutOfCountersError(batchResponse.ErrorRom)
|
| 19 |
-
readWriteAddresses, err := convertToReadWriteAddressesV2(batchResponse.ReadWriteAddresses)
|
| 20 |
-
if err != nil {
|
| 21 |
-
return nil, err
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
return &ProcessBatchResponse{
|
| 25 |
-
NewStateRoot: common.BytesToHash(batchResponse.NewStateRoot),
|
| 26 |
-
NewAccInputHash: common.BytesToHash(batchResponse.NewAccInputHash),
|
| 27 |
-
NewLocalExitRoot: common.BytesToHash(batchResponse.NewLocalExitRoot),
|
| 28 |
-
UsedZkCounters: convertToUsedZKCountersV3(batchResponse),
|
| 29 |
-
ReservedZkCounters: convertToReservedZKCountersV3(batchResponse),
|
| 30 |
-
BlockResponses: blockResponses,
|
| 31 |
-
ExecutorError: executor.ExecutorErr(batchResponse.Error),
|
| 32 |
-
ReadWriteAddresses: readWriteAddresses,
|
| 33 |
-
FlushID: batchResponse.FlushId,
|
| 34 |
-
StoredFlushID: batchResponse.StoredFlushId,
|
| 35 |
-
ProverID: batchResponse.ProverId,
|
| 36 |
-
IsExecutorLevelError: batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR,
|
| 37 |
-
IsRomLevelError: isRomLevelError,
|
| 38 |
-
IsRomOOCError: isRomOOCError,
|
| 39 |
-
GasUsed_V2: batchResponse.GasUsed,
|
| 40 |
-
SMTKeys_V2: convertToKeys(batchResponse.SmtKeys),
|
| 41 |
-
ProgramKeys_V2: convertToKeys(batchResponse.ProgramKeys),
|
| 42 |
-
ForkID: batchResponse.ForkId,
|
| 43 |
-
InvalidBatch_V2: batchResponse.InvalidBatch != 0,
|
| 44 |
-
RomError_V2: executor.RomErr(batchResponse.ErrorRom),
|
| 45 |
-
OldStateRoot_V2: common.BytesToHash(batchResponse.OldStateRoot),
|
| 46 |
-
NewLastTimestamp_V3: batchResponse.NewLastTimestamp,
|
| 47 |
-
CurrentL1InfoTreeRoot_V3: common.BytesToHash(batchResponse.CurrentL1InfoTreeRoot),
|
| 48 |
-
CurrentL1InfoTreeIndex_V3: batchResponse.CurrentL1InfoTreeIndex,
|
| 49 |
-
}, nil
|
| 50 |
-
}
|
| 51 |
-
|
| 52 |
-
func convertToUsedZKCountersV3(resp *executor.ProcessBatchResponseV3) ZKCounters {
|
| 53 |
-
return ZKCounters{
|
| 54 |
-
GasUsed: resp.GasUsed,
|
| 55 |
-
KeccakHashes: resp.CntKeccakHashes,
|
| 56 |
-
PoseidonHashes: resp.CntPoseidonHashes,
|
| 57 |
-
PoseidonPaddings: resp.CntPoseidonPaddings,
|
| 58 |
-
MemAligns: resp.CntMemAligns,
|
| 59 |
-
Arithmetics: resp.CntArithmetics,
|
| 60 |
-
Binaries: resp.CntBinaries,
|
| 61 |
-
Steps: resp.CntSteps,
|
| 62 |
-
Sha256Hashes_V2: resp.CntSha256Hashes,
|
| 63 |
-
}
|
| 64 |
-
}
|
| 65 |
-
|
| 66 |
-
func convertToReservedZKCountersV3(resp *executor.ProcessBatchResponseV3) ZKCounters {
|
| 67 |
-
return ZKCounters{
|
| 68 |
-
// There is no "ReserveGasUsed" in the response, so we use "GasUsed" as it will make calculations easier
|
| 69 |
-
GasUsed: resp.GasUsed,
|
| 70 |
-
KeccakHashes: resp.CntReserveKeccakHashes,
|
| 71 |
-
PoseidonHashes: resp.CntReservePoseidonHashes,
|
| 72 |
-
PoseidonPaddings: resp.CntReservePoseidonPaddings,
|
| 73 |
-
MemAligns: resp.CntReserveMemAligns,
|
| 74 |
-
Arithmetics: resp.CntReserveArithmetics,
|
| 75 |
-
Binaries: resp.CntReserveBinaries,
|
| 76 |
-
Steps: resp.CntReserveSteps,
|
| 77 |
-
Sha256Hashes_V2: resp.CntReserveSha256Hashes,
|
| 78 |
-
}
|
| 79 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -80,6 +80,7 @@
|
|
| 80 |
Coinbase common.Address // 20 bytes
|
| 81 |
ForkID uint16 // 2 bytes
|
| 82 |
ChainID uint32 // 4 bytes
|
|
|
|
| 83 |
}
|
| 84 |
|
| 85 |
// Encode returns the encoded DSL2BlockStart as a byte slice
|
|
@@ -110,6 +111,7 @@
|
|
| 110 |
b.Coinbase = common.BytesToAddress(data[96:116])
|
| 111 |
b.ForkID = binary.BigEndian.Uint16(data[116:118])
|
| 112 |
b.ChainID = binary.BigEndian.Uint32(data[118:122])
|
|
|
|
| 113 |
return b
|
| 114 |
}
|
| 115 |
|
|
|
|
| 80 |
Coinbase common.Address // 20 bytes
|
| 81 |
ForkID uint16 // 2 bytes
|
| 82 |
ChainID uint32 // 4 bytes
|
| 83 |
+
|
| 84 |
}
|
| 85 |
|
| 86 |
// Encode returns the encoded DSL2BlockStart as a byte slice
|
|
|
|
| 111 |
b.Coinbase = common.BytesToAddress(data[96:116])
|
| 112 |
b.ForkID = binary.BigEndian.Uint16(data[116:118])
|
| 113 |
b.ChainID = binary.BigEndian.Uint32(data[118:122])
|
| 114 |
+
|
| 115 |
return b
|
| 116 |
}
|
| 117 |
|
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package state
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"errors"
|
| 5 |
+
"math/big"
|
| 6 |
+
)
|
| 7 |
+
|
| 8 |
+
const (
|
| 9 |
+
// MaxEffectivePercentage is the maximum value that can be used as effective percentage
|
| 10 |
+
MaxEffectivePercentage = uint8(255)
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
var (
|
| 14 |
+
// ErrEffectiveGasPriceEmpty happens when the effectiveGasPrice or gasPrice is nil or zero
|
| 15 |
+
ErrEffectiveGasPriceEmpty = errors.New("effectiveGasPrice or gasPrice cannot be nil or zero")
|
| 16 |
+
|
| 17 |
+
// ErrEffectiveGasPriceIsZero happens when the calculated EffectiveGasPrice is zero
|
| 18 |
+
ErrEffectiveGasPriceIsZero = errors.New("effectiveGasPrice cannot be zero")
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 22 |
+
func CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 23 |
+
const bits = 256
|
| 24 |
+
var bitsBigInt = big.NewInt(bits)
|
| 25 |
+
|
| 26 |
+
if effectiveGasPrice == nil || gasPrice == nil ||
|
| 27 |
+
gasPrice.Cmp(big.NewInt(0)) == 0 || effectiveGasPrice.Cmp(big.NewInt(0)) == 0 {
|
| 28 |
+
return 0, ErrEffectiveGasPriceEmpty
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
if gasPrice.Cmp(effectiveGasPrice) <= 0 {
|
| 32 |
+
return MaxEffectivePercentage, nil
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// Simulate Ceil with integer division
|
| 36 |
+
b := new(big.Int).Mul(effectiveGasPrice, bitsBigInt)
|
| 37 |
+
b = b.Add(b, gasPrice)
|
| 38 |
+
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 39 |
+
b = b.Div(b, gasPrice)
|
| 40 |
+
// At this point we have a percentage between 1-256, we need to sub 1 to have it between 0-255 (byte)
|
| 41 |
+
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 42 |
+
|
| 43 |
+
return uint8(b.Uint64()), nil
|
| 44 |
+
}
|
|
@@ -2,13 +2,7 @@
|
|
| 2 |
This file provide functions to work with ETROG batches:
|
| 3 |
- EncodeBatchV2 (equivalent to EncodeTransactions)
|
| 4 |
- DecodeBatchV2 (equivalent to DecodeTxs)
|
| 5 |
-
- DecodeForcedBatchV2
|
| 6 |
-
|
| 7 |
-
Also provide a builder class to create batches (BatchV2Encoder):
|
| 8 |
-
This method doesnt check anything, so is more flexible but you need to know what you are doing
|
| 9 |
-
- `builder := NewBatchV2Encoder()` : Create a new `BatchV2Encoder``
|
| 10 |
-
- You can call to `AddBlockHeader` or `AddTransaction` to add a block header or a transaction as you wish
|
| 11 |
-
- You can call to `GetResult` to get the batch data
|
| 12 |
|
| 13 |
|
| 14 |
// batch data format:
|
|
@@ -33,25 +27,11 @@
|
|
| 33 |
// 0x00 | 32 | V
|
| 34 |
// 0x00 | 1 | efficiencyPercentage
|
| 35 |
// Repeat Transaction
|
| 36 |
-
//
|
| 37 |
-
// Usage:
|
| 38 |
-
// There are 2 ways of use this module, direct calls or a builder class:
|
| 39 |
-
// 1) Direct calls:
|
| 40 |
-
// - EncodeBatchV2: Encode a batch of transactions
|
| 41 |
-
// - DecodeBatchV2: Decode a batch of transactions
|
| 42 |
-
//
|
| 43 |
-
// 2) Builder class:
|
| 44 |
-
// This method doesnt check anything, so is more flexible but you need to know what you are doing
|
| 45 |
-
// - builder := NewBatchV2Encoder(): Create a new BatchV2Encoder
|
| 46 |
-
// - You can call to `AddBlockHeader` or `AddTransaction` to add a block header or a transaction as you wish
|
| 47 |
-
// - You can call to `GetResult` to get the batch data
|
| 48 |
-
|
| 49 |
*/
|
| 50 |
|
| 51 |
package state
|
| 52 |
|
| 53 |
import (
|
| 54 |
-
"encoding/binary"
|
| 55 |
"errors"
|
| 56 |
"fmt"
|
| 57 |
"strconv"
|
|
@@ -62,16 +42,11 @@
|
|
| 62 |
"github.com/ethereum/go-ethereum/rlp"
|
| 63 |
)
|
| 64 |
|
| 65 |
-
// ChangeL2BlockHeader is the header of a L2 block.
|
| 66 |
-
type ChangeL2BlockHeader struct {
|
| 67 |
-
DeltaTimestamp uint32
|
| 68 |
-
IndexL1InfoTree uint32
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
// L2BlockRaw is the raw representation of a L2 block.
|
| 72 |
type L2BlockRaw struct {
|
| 73 |
-
|
| 74 |
-
|
|
|
|
| 75 |
}
|
| 76 |
|
| 77 |
// BatchRawV2 is the representation of a batch of transactions.
|
|
@@ -86,15 +61,12 @@
|
|
| 86 |
|
| 87 |
// L2TxRaw is the raw representation of a L2 transaction inside a L2 block.
|
| 88 |
type L2TxRaw struct {
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
Tx types.Transaction // valid if TxAlreadyEncoded == false
|
| 92 |
-
Data []byte // valid if TxAlreadyEncoded == true
|
| 93 |
}
|
| 94 |
|
| 95 |
const (
|
| 96 |
changeL2Block = uint8(0x0b)
|
| 97 |
-
sizeUInt32 = 4
|
| 98 |
)
|
| 99 |
|
| 100 |
var (
|
|
@@ -120,88 +92,57 @@
|
|
| 120 |
|
| 121 |
// EncodeBatchV2 encodes a batch of transactions into a byte slice.
|
| 122 |
func EncodeBatchV2(batch *BatchRawV2) ([]byte, error) {
|
|
|
|
|
|
|
| 123 |
if batch == nil {
|
| 124 |
return nil, fmt.Errorf("batch is nil: %w", ErrInvalidBatchV2)
|
| 125 |
}
|
| 126 |
-
|
|
|
|
| 127 |
return nil, fmt.Errorf("a batch need minimum a L2Block: %w", ErrInvalidBatchV2)
|
| 128 |
}
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
for _, block := range batch.Blocks {
|
| 132 |
-
encoder.AddBlockHeader(block.ChangeL2BlockHeader)
|
| 133 |
-
err := encoder.AddTransactions(block.Transactions)
|
| 134 |
if err != nil {
|
| 135 |
-
return nil, fmt.Errorf("can't encode
|
| 136 |
}
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
type BatchV2Encoder struct {
|
| 143 |
-
batchData []byte
|
| 144 |
-
}
|
| 145 |
-
|
| 146 |
-
// NewBatchV2Encoder creates a new BatchV2Encoder.
|
| 147 |
-
func NewBatchV2Encoder() *BatchV2Encoder {
|
| 148 |
-
return &BatchV2Encoder{}
|
| 149 |
-
}
|
| 150 |
-
|
| 151 |
-
// AddBlockHeader adds a block header to the batch.
|
| 152 |
-
func (b *BatchV2Encoder) AddBlockHeader(l2BlockHeader ChangeL2BlockHeader) {
|
| 153 |
-
b.batchData = l2BlockHeader.Encode(b.batchData)
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
// AddTransactions adds a set of transactions to the batch.
|
| 157 |
-
func (b *BatchV2Encoder) AddTransactions(transactions []L2TxRaw) error {
|
| 158 |
-
for _, tx := range transactions {
|
| 159 |
-
err := b.AddTransaction(tx)
|
| 160 |
-
if err != nil {
|
| 161 |
-
return fmt.Errorf("can't encode tx: %w", err)
|
| 162 |
}
|
| 163 |
}
|
| 164 |
-
return nil
|
| 165 |
-
}
|
| 166 |
-
|
| 167 |
-
// AddTransaction adds a transaction to the batch.
|
| 168 |
-
func (b *BatchV2Encoder) AddTransaction(transaction L2TxRaw) error {
|
| 169 |
-
var err error
|
| 170 |
-
b.batchData, err = transaction.Encode(b.batchData)
|
| 171 |
-
if err != nil {
|
| 172 |
-
return fmt.Errorf("can't encode tx: %w", err)
|
| 173 |
-
}
|
| 174 |
-
return nil
|
| 175 |
-
}
|
| 176 |
-
|
| 177 |
-
// GetResult returns the batch data.
|
| 178 |
-
func (b *BatchV2Encoder) GetResult() []byte {
|
| 179 |
-
return b.batchData
|
| 180 |
}
|
| 181 |
|
| 182 |
-
//
|
| 183 |
-
func (
|
| 184 |
batchData = append(batchData, changeL2Block)
|
| 185 |
-
batchData = append(batchData,
|
| 186 |
-
batchData = append(batchData,
|
| 187 |
-
return batchData
|
| 188 |
}
|
| 189 |
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
if
|
| 193 |
-
|
| 194 |
-
} else {
|
| 195 |
-
rlpTx, err := prepareRLPTxData(tx.Tx)
|
| 196 |
-
if err != nil {
|
| 197 |
-
return nil, fmt.Errorf("can't encode tx to RLP: %w", err)
|
| 198 |
-
}
|
| 199 |
-
batchData = append(batchData, rlpTx...)
|
| 200 |
}
|
|
|
|
| 201 |
batchData = append(batchData, tx.EfficiencyPercentage)
|
| 202 |
return batchData, nil
|
| 203 |
}
|
| 204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
// DecodeBatchV2 decodes a batch of transactions from a byte slice.
|
| 206 |
func DecodeBatchV2(txsData []byte) (*BatchRawV2, error) {
|
| 207 |
// The transactions is not RLP encoded. Is the raw bytes in this form: 1 byte for the transaction type (always 0b for changeL2Block) + 4 bytes for deltaTimestamp + for bytes for indexL1InfoTree
|
|
@@ -223,7 +164,7 @@
|
|
| 223 |
// is a tx
|
| 224 |
default:
|
| 225 |
if currentBlock == nil {
|
| 226 |
-
_, _, err :=
|
| 227 |
if err == nil {
|
| 228 |
// There is no changeL2Block but have a valid RLP transaction
|
| 229 |
return nil, ErrBatchV2DontStartWithChangeL2Block
|
|
@@ -233,7 +174,7 @@
|
|
| 233 |
}
|
| 234 |
}
|
| 235 |
var tx *L2TxRaw
|
| 236 |
-
pos, tx, err =
|
| 237 |
if err != nil {
|
| 238 |
return nil, fmt.Errorf("can't decode transactions: %w", err)
|
| 239 |
}
|
|
@@ -274,11 +215,11 @@
|
|
| 274 |
func decodeBlockHeader(txsData []byte, pos int) (int, *L2BlockRaw, error) {
|
| 275 |
var err error
|
| 276 |
currentBlock := &L2BlockRaw{}
|
| 277 |
-
pos, currentBlock.DeltaTimestamp, err =
|
| 278 |
if err != nil {
|
| 279 |
return 0, nil, fmt.Errorf("can't get deltaTimestamp: %w", err)
|
| 280 |
}
|
| 281 |
-
pos, currentBlock.IndexL1InfoTree, err =
|
| 282 |
if err != nil {
|
| 283 |
return 0, nil, fmt.Errorf("can't get leafIndex: %w", err)
|
| 284 |
}
|
|
@@ -286,8 +227,7 @@
|
|
| 286 |
return pos, currentBlock, nil
|
| 287 |
}
|
| 288 |
|
| 289 |
-
|
| 290 |
-
func DecodeTxRLP(txsData []byte, offset int) (int, *L2TxRaw, error) {
|
| 291 |
var err error
|
| 292 |
length, err := decodeRLPListLengthFromOffset(txsData, offset)
|
| 293 |
if err != nil {
|
|
@@ -325,6 +265,13 @@
|
|
| 325 |
return int(endPos), l2Tx, err
|
| 326 |
}
|
| 327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
// It returns the length of data from the param offset
|
| 329 |
// ex:
|
| 330 |
// 0xc0 -> empty data -> 1 byte because it include the 0xc0
|
|
@@ -355,16 +302,3 @@
|
|
| 355 |
}
|
| 356 |
return length + headerByteLength, nil
|
| 357 |
}
|
| 358 |
-
|
| 359 |
-
func encodeUint32(value uint32) []byte {
|
| 360 |
-
data := make([]byte, sizeUInt32)
|
| 361 |
-
binary.BigEndian.PutUint32(data, value)
|
| 362 |
-
return data
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
func decodeUint32(txsData []byte, pos int) (int, uint32, error) {
|
| 366 |
-
if len(txsData)-pos < sizeUInt32 {
|
| 367 |
-
return 0, 0, fmt.Errorf("can't get u32 because not enough data: %w", ErrInvalidBatchV2)
|
| 368 |
-
}
|
| 369 |
-
return pos + sizeUInt32, binary.BigEndian.Uint32(txsData[pos : pos+sizeUInt32]), nil
|
| 370 |
-
}
|
|
|
|
| 2 |
This file provide functions to work with ETROG batches:
|
| 3 |
- EncodeBatchV2 (equivalent to EncodeTransactions)
|
| 4 |
- DecodeBatchV2 (equivalent to DecodeTxs)
|
| 5 |
+
- DecodeForcedBatchV2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
// batch data format:
|
|
|
|
| 27 |
// 0x00 | 32 | V
|
| 28 |
// 0x00 | 1 | efficiencyPercentage
|
| 29 |
// Repeat Transaction
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
*/
|
| 31 |
|
| 32 |
package state
|
| 33 |
|
| 34 |
import (
|
|
|
|
| 35 |
"errors"
|
| 36 |
"fmt"
|
| 37 |
"strconv"
|
|
|
|
| 42 |
"github.com/ethereum/go-ethereum/rlp"
|
| 43 |
)
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
// L2BlockRaw is the raw representation of a L2 block.
|
| 46 |
type L2BlockRaw struct {
|
| 47 |
+
DeltaTimestamp uint32
|
| 48 |
+
IndexL1InfoTree uint32
|
| 49 |
+
Transactions []L2TxRaw
|
| 50 |
}
|
| 51 |
|
| 52 |
// BatchRawV2 is the representation of a batch of transactions.
|
|
|
|
| 61 |
|
| 62 |
// L2TxRaw is the raw representation of a L2 transaction inside a L2 block.
|
| 63 |
type L2TxRaw struct {
|
| 64 |
+
Tx types.Transaction
|
| 65 |
+
EfficiencyPercentage uint8
|
|
|
|
|
|
|
| 66 |
}
|
| 67 |
|
| 68 |
const (
|
| 69 |
changeL2Block = uint8(0x0b)
|
|
|
|
| 70 |
)
|
| 71 |
|
| 72 |
var (
|
|
|
|
| 92 |
|
| 93 |
// EncodeBatchV2 encodes a batch of transactions into a byte slice.
|
| 94 |
func EncodeBatchV2(batch *BatchRawV2) ([]byte, error) {
|
| 95 |
+
var err error
|
| 96 |
+
var batchData []byte
|
| 97 |
if batch == nil {
|
| 98 |
return nil, fmt.Errorf("batch is nil: %w", ErrInvalidBatchV2)
|
| 99 |
}
|
| 100 |
+
blocks := batch.Blocks
|
| 101 |
+
if len(blocks) == 0 {
|
| 102 |
return nil, fmt.Errorf("a batch need minimum a L2Block: %w", ErrInvalidBatchV2)
|
| 103 |
}
|
| 104 |
+
for _, block := range blocks {
|
| 105 |
+
batchData, err = EncodeBlockHeaderV2(batchData, block)
|
|
|
|
|
|
|
|
|
|
| 106 |
if err != nil {
|
| 107 |
+
return nil, fmt.Errorf("can't encode block header: %w", err)
|
| 108 |
}
|
| 109 |
+
for _, tx := range block.Transactions {
|
| 110 |
+
batchData, err = encodeTxRLP(batchData, tx)
|
| 111 |
+
if err != nil {
|
| 112 |
+
return nil, fmt.Errorf("can't encode tx: %w", err)
|
| 113 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
}
|
| 115 |
}
|
| 116 |
+
return batchData, nil
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
}
|
| 118 |
|
| 119 |
+
// EncodeBlockHeaderV2 encodes a batch of l2blocks header into a byte slice.
|
| 120 |
+
func EncodeBlockHeaderV2(batchData []byte, block L2BlockRaw) ([]byte, error) {
|
| 121 |
batchData = append(batchData, changeL2Block)
|
| 122 |
+
batchData = append(batchData, serializeUint32(block.DeltaTimestamp)...)
|
| 123 |
+
batchData = append(batchData, serializeUint32(block.IndexL1InfoTree)...)
|
| 124 |
+
return batchData, nil
|
| 125 |
}
|
| 126 |
|
| 127 |
+
func encodeTxRLP(batchData []byte, tx L2TxRaw) ([]byte, error) {
|
| 128 |
+
rlpTx, err := prepareRPLTxData(tx.Tx)
|
| 129 |
+
if err != nil {
|
| 130 |
+
return nil, fmt.Errorf("can't encode tx to RLP: %w", err)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
}
|
| 132 |
+
batchData = append(batchData, rlpTx...)
|
| 133 |
batchData = append(batchData, tx.EfficiencyPercentage)
|
| 134 |
return batchData, nil
|
| 135 |
}
|
| 136 |
|
| 137 |
+
func serializeUint32(value uint32) []byte {
|
| 138 |
+
return []byte{
|
| 139 |
+
byte(value >> 24), // nolint:gomnd
|
| 140 |
+
byte(value >> 16), // nolint:gomnd
|
| 141 |
+
byte(value >> 8), // nolint:gomnd
|
| 142 |
+
byte(value),
|
| 143 |
+
} // nolint:gomnd
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
// DecodeBatchV2 decodes a batch of transactions from a byte slice.
|
| 147 |
func DecodeBatchV2(txsData []byte) (*BatchRawV2, error) {
|
| 148 |
// The transactions is not RLP encoded. Is the raw bytes in this form: 1 byte for the transaction type (always 0b for changeL2Block) + 4 bytes for deltaTimestamp + for bytes for indexL1InfoTree
|
|
|
|
| 164 |
// is a tx
|
| 165 |
default:
|
| 166 |
if currentBlock == nil {
|
| 167 |
+
_, _, err := decodeTxRLP(txsData, pos)
|
| 168 |
if err == nil {
|
| 169 |
// There is no changeL2Block but have a valid RLP transaction
|
| 170 |
return nil, ErrBatchV2DontStartWithChangeL2Block
|
|
|
|
| 174 |
}
|
| 175 |
}
|
| 176 |
var tx *L2TxRaw
|
| 177 |
+
pos, tx, err = decodeTxRLP(txsData, pos)
|
| 178 |
if err != nil {
|
| 179 |
return nil, fmt.Errorf("can't decode transactions: %w", err)
|
| 180 |
}
|
|
|
|
| 215 |
func decodeBlockHeader(txsData []byte, pos int) (int, *L2BlockRaw, error) {
|
| 216 |
var err error
|
| 217 |
currentBlock := &L2BlockRaw{}
|
| 218 |
+
pos, currentBlock.DeltaTimestamp, err = deserializeUint32(txsData, pos)
|
| 219 |
if err != nil {
|
| 220 |
return 0, nil, fmt.Errorf("can't get deltaTimestamp: %w", err)
|
| 221 |
}
|
| 222 |
+
pos, currentBlock.IndexL1InfoTree, err = deserializeUint32(txsData, pos)
|
| 223 |
if err != nil {
|
| 224 |
return 0, nil, fmt.Errorf("can't get leafIndex: %w", err)
|
| 225 |
}
|
|
|
|
| 227 |
return pos, currentBlock, nil
|
| 228 |
}
|
| 229 |
|
| 230 |
+
func decodeTxRLP(txsData []byte, offset int) (int, *L2TxRaw, error) {
|
|
|
|
| 231 |
var err error
|
| 232 |
length, err := decodeRLPListLengthFromOffset(txsData, offset)
|
| 233 |
if err != nil {
|
|
|
|
| 265 |
return int(endPos), l2Tx, err
|
| 266 |
}
|
| 267 |
|
| 268 |
+
func deserializeUint32(txsData []byte, pos int) (int, uint32, error) {
|
| 269 |
+
if len(txsData)-pos < 4 { // nolint:gomnd
|
| 270 |
+
return 0, 0, fmt.Errorf("can't get u32 because not enough data: %w", ErrInvalidBatchV2)
|
| 271 |
+
}
|
| 272 |
+
return pos + 4, uint32(txsData[pos])<<24 | uint32(txsData[pos+1])<<16 | uint32(txsData[pos+2])<<8 | uint32(txsData[pos+3]), nil // nolint:gomnd
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
// It returns the length of data from the param offset
|
| 276 |
// ex:
|
| 277 |
// 0xc0 -> empty data -> 1 byte because it include the 0xc0
|
|
|
|
| 302 |
}
|
| 303 |
return length + headerByteLength, nil
|
| 304 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -186,19 +186,14 @@
|
|
| 186 |
|
| 187 |
func TestEncodeBatchV2(t *testing.T) {
|
| 188 |
block1 := L2BlockRaw{
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
},
|
| 193 |
-
Transactions: []L2TxRaw{},
|
| 194 |
}
|
| 195 |
-
|
| 196 |
block2 := L2BlockRaw{
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
},
|
| 201 |
-
Transactions: []L2TxRaw{},
|
| 202 |
}
|
| 203 |
blocks := []L2BlockRaw{block1, block2}
|
| 204 |
|
|
@@ -244,36 +239,3 @@
|
|
| 244 |
_, err = DecodeForcedBatchV2(batchL2Data)
|
| 245 |
require.Error(t, err)
|
| 246 |
}
|
| 247 |
-
|
| 248 |
-
func TestEncodeBatchV2WithTxInBinary(t *testing.T) {
|
| 249 |
-
block1 := L2BlockRaw{
|
| 250 |
-
ChangeL2BlockHeader: ChangeL2BlockHeader{
|
| 251 |
-
DeltaTimestamp: 123,
|
| 252 |
-
IndexL1InfoTree: 456,
|
| 253 |
-
},
|
| 254 |
-
Transactions: []L2TxRaw{
|
| 255 |
-
{
|
| 256 |
-
EfficiencyPercentage: 255,
|
| 257 |
-
TxAlreadyEncoded: true,
|
| 258 |
-
Data: []byte{0x01, 0x02, 0x03},
|
| 259 |
-
},
|
| 260 |
-
},
|
| 261 |
-
}
|
| 262 |
-
|
| 263 |
-
block2 := L2BlockRaw{
|
| 264 |
-
ChangeL2BlockHeader: ChangeL2BlockHeader{
|
| 265 |
-
DeltaTimestamp: 789,
|
| 266 |
-
IndexL1InfoTree: 101112,
|
| 267 |
-
},
|
| 268 |
-
Transactions: []L2TxRaw{},
|
| 269 |
-
}
|
| 270 |
-
blocks := []L2BlockRaw{block1, block2}
|
| 271 |
-
|
| 272 |
-
expectedBatchData := []byte{
|
| 273 |
-
0xb, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x1, 0xc8, 0x1, 0x2, 0x3, 0xff, 0xb, 0x0, 0x0, 0x3, 0x15, 0x0, 0x1, 0x8a, 0xf8,
|
| 274 |
-
}
|
| 275 |
-
|
| 276 |
-
batchData, err := EncodeBatchV2(&BatchRawV2{Blocks: blocks})
|
| 277 |
-
require.NoError(t, err)
|
| 278 |
-
require.Equal(t, expectedBatchData, batchData)
|
| 279 |
-
}
|
|
|
|
| 186 |
|
| 187 |
func TestEncodeBatchV2(t *testing.T) {
|
| 188 |
block1 := L2BlockRaw{
|
| 189 |
+
DeltaTimestamp: 123,
|
| 190 |
+
IndexL1InfoTree: 456,
|
| 191 |
+
Transactions: []L2TxRaw{},
|
|
|
|
|
|
|
| 192 |
}
|
|
|
|
| 193 |
block2 := L2BlockRaw{
|
| 194 |
+
DeltaTimestamp: 789,
|
| 195 |
+
IndexL1InfoTree: 101112,
|
| 196 |
+
Transactions: []L2TxRaw{},
|
|
|
|
|
|
|
| 197 |
}
|
| 198 |
blocks := []L2BlockRaw{block1, block2}
|
| 199 |
|
|
|
|
| 239 |
_, err = DecodeForcedBatchV2(batchL2Data)
|
| 240 |
require.Error(t, err)
|
| 241 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -17,10 +17,8 @@
|
|
| 17 |
FORKID_ETROG = 7
|
| 18 |
// FORKID_ELDERBERRY is the fork id 8
|
| 19 |
FORKID_ELDERBERRY = 8
|
| 20 |
-
//
|
| 21 |
-
|
| 22 |
-
// FORKID_FEIJOA is the fork id 10
|
| 23 |
-
FORKID_FEIJOA = 10
|
| 24 |
)
|
| 25 |
|
| 26 |
// ForkIDInterval is a fork id interval
|
|
|
|
| 17 |
FORKID_ETROG = 7
|
| 18 |
// FORKID_ELDERBERRY is the fork id 8
|
| 19 |
FORKID_ELDERBERRY = 8
|
| 20 |
+
// FORKID_9 is the fork id 9
|
| 21 |
+
FORKID_9 = 9
|
|
|
|
|
|
|
| 22 |
)
|
| 23 |
|
| 24 |
// ForkIDInterval is a fork id interval
|
|
@@ -19,8 +19,10 @@
|
|
| 19 |
|
| 20 |
// Genesis contains the information to populate state on creation
|
| 21 |
type Genesis struct {
|
| 22 |
-
//
|
| 23 |
-
|
|
|
|
|
|
|
| 24 |
// Root hash of the genesis block
|
| 25 |
Root common.Hash
|
| 26 |
// Actions is the data to populate into the state trie
|
|
|
|
| 19 |
|
| 20 |
// Genesis contains the information to populate state on creation
|
| 21 |
type Genesis struct {
|
| 22 |
+
// RollupBlockNumber is the block number where the polygonZKEVM smc was deployed on L1
|
| 23 |
+
RollupBlockNumber uint64
|
| 24 |
+
// RollupManagerBlockNumber is the block number where the RollupManager smc was deployed on L1
|
| 25 |
+
RollupManagerBlockNumber uint64
|
| 26 |
// Root hash of the genesis block
|
| 27 |
Root common.Hash
|
| 28 |
// Actions is the data to populate into the state trie
|
|
@@ -18,8 +18,6 @@
|
|
| 18 |
double = 2
|
| 19 |
ether155V = 27
|
| 20 |
etherPre155V = 35
|
| 21 |
-
// MaxEffectivePercentage is the maximum value that can be used as effective percentage
|
| 22 |
-
MaxEffectivePercentage = uint8(255)
|
| 23 |
// Decoding constants
|
| 24 |
headerByteLength uint64 = 1
|
| 25 |
sLength uint64 = 32
|
|
@@ -39,7 +37,7 @@
|
|
| 39 |
var batchL2Data []byte
|
| 40 |
|
| 41 |
for i, tx := range txs {
|
| 42 |
-
txData, err :=
|
| 43 |
if err != nil {
|
| 44 |
return nil, err
|
| 45 |
}
|
|
@@ -57,7 +55,7 @@
|
|
| 57 |
return batchL2Data, nil
|
| 58 |
}
|
| 59 |
|
| 60 |
-
func
|
| 61 |
v, r, s := tx.RawSignatureValues()
|
| 62 |
sign := 1 - (v.Uint64() & 1)
|
| 63 |
|
|
@@ -99,7 +97,7 @@
|
|
| 99 |
var batchL2Data []byte
|
| 100 |
|
| 101 |
for _, tx := range txs {
|
| 102 |
-
txData, err :=
|
| 103 |
if err != nil {
|
| 104 |
return nil, err
|
| 105 |
}
|
|
|
|
| 18 |
double = 2
|
| 19 |
ether155V = 27
|
| 20 |
etherPre155V = 35
|
|
|
|
|
|
|
| 21 |
// Decoding constants
|
| 22 |
headerByteLength uint64 = 1
|
| 23 |
sLength uint64 = 32
|
|
|
|
| 37 |
var batchL2Data []byte
|
| 38 |
|
| 39 |
for i, tx := range txs {
|
| 40 |
+
txData, err := prepareRPLTxData(tx)
|
| 41 |
if err != nil {
|
| 42 |
return nil, err
|
| 43 |
}
|
|
|
|
| 55 |
return batchL2Data, nil
|
| 56 |
}
|
| 57 |
|
| 58 |
+
func prepareRPLTxData(tx types.Transaction) ([]byte, error) {
|
| 59 |
v, r, s := tx.RawSignatureValues()
|
| 60 |
sign := 1 - (v.Uint64() & 1)
|
| 61 |
|
|
|
|
| 97 |
var batchL2Data []byte
|
| 98 |
|
| 99 |
for _, tx := range txs {
|
| 100 |
+
txData, err := prepareRPLTxData(tx)
|
| 101 |
if err != nil {
|
| 102 |
return nil, err
|
| 103 |
}
|
|
@@ -103,14 +103,14 @@
|
|
| 103 |
GetSequences(ctx context.Context, lastVerifiedBatchNumber uint64, dbTx pgx.Tx) ([]Sequence, error)
|
| 104 |
GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*Batch, error)
|
| 105 |
CheckProofContainsCompleteSequences(ctx context.Context, proof *Proof, dbTx pgx.Tx) (bool, error)
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
GetLastClosedBatch(ctx context.Context, dbTx pgx.Tx) (*Batch, error)
|
| 115 |
GetLastClosedBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 116 |
UpdateBatchL2Data(ctx context.Context, batchNumber uint64, batchL2Data []byte, dbTx pgx.Tx) error
|
|
@@ -145,6 +145,7 @@
|
|
| 145 |
GetForkIDByBlockNumber(blockNumber uint64) uint64
|
| 146 |
GetForkIDByBatchNumber(batchNumber uint64) uint64
|
| 147 |
GetLatestIndex(ctx context.Context, dbTx pgx.Tx) (uint32, error)
|
|
|
|
| 148 |
GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error)
|
| 149 |
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
| 150 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
|
@@ -152,6 +153,9 @@
|
|
| 152 |
GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
| 153 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 154 |
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
|
|
|
|
|
|
|
|
|
| 155 |
GetLatestBatchGlobalExitRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error)
|
| 156 |
GetL2TxHashByTxHash(ctx context.Context, hash common.Hash, dbTx pgx.Tx) (*common.Hash, error)
|
| 157 |
GetSyncInfoData(ctx context.Context, dbTx pgx.Tx) (SyncInfoDataOnStorage, error)
|
|
@@ -162,20 +166,4 @@
|
|
| 162 |
GetNotCheckedBatches(ctx context.Context, dbTx pgx.Tx) ([]*Batch, error)
|
| 163 |
GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*L2Block, error)
|
| 164 |
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
| 165 |
-
AddL1InfoTreeRecursiveRootToExitRoot(ctx context.Context, exitRoot *L1InfoTreeRecursiveExitRootStorageEntry, dbTx pgx.Tx) error
|
| 166 |
-
GetAllL1InfoTreeRecursiveRootEntries(ctx context.Context, dbTx pgx.Tx) ([]L1InfoTreeRecursiveExitRootStorageEntry, error)
|
| 167 |
-
GetLatestL1InfoTreeRecursiveRoot(ctx context.Context, maxBlockNumber uint64, dbTx pgx.Tx) (L1InfoTreeRecursiveExitRootStorageEntry, error)
|
| 168 |
-
GetL1InfoRecursiveRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
| 169 |
-
|
| 170 |
-
storeblobsequences
|
| 171 |
-
storeblobinner
|
| 172 |
-
}
|
| 173 |
-
|
| 174 |
-
type storeblobsequences interface {
|
| 175 |
-
AddBlobSequence(ctx context.Context, blobSequence *BlobSequence, dbTx pgx.Tx) error
|
| 176 |
-
GetLastBlobSequence(ctx context.Context, dbTx pgx.Tx) (*BlobSequence, error)
|
| 177 |
-
}
|
| 178 |
-
|
| 179 |
-
type storeblobinner interface {
|
| 180 |
-
AddBlobInner(ctx context.Context, blobInner *BlobInner, dbTx pgx.Tx) error
|
| 181 |
}
|
|
|
|
| 103 |
GetSequences(ctx context.Context, lastVerifiedBatchNumber uint64, dbTx pgx.Tx) ([]Sequence, error)
|
| 104 |
GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*Batch, error)
|
| 105 |
CheckProofContainsCompleteSequences(ctx context.Context, proof *Proof, dbTx pgx.Tx) (bool, error)
|
| 106 |
+
GetProofReadyToVerify(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*Proof, error)
|
| 107 |
+
GetProofsToAggregate(ctx context.Context, dbTx pgx.Tx) (*Proof, *Proof, error)
|
| 108 |
+
AddGeneratedProof(ctx context.Context, proof *Proof, dbTx pgx.Tx) error
|
| 109 |
+
UpdateGeneratedProof(ctx context.Context, proof *Proof, dbTx pgx.Tx) error
|
| 110 |
+
DeleteGeneratedProofs(ctx context.Context, batchNumber uint64, batchNumberFinal uint64, dbTx pgx.Tx) error
|
| 111 |
+
CleanupGeneratedProofs(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
| 112 |
+
CleanupLockedProofs(ctx context.Context, duration string, dbTx pgx.Tx) (int64, error)
|
| 113 |
+
DeleteUngeneratedProofs(ctx context.Context, dbTx pgx.Tx) error
|
| 114 |
GetLastClosedBatch(ctx context.Context, dbTx pgx.Tx) (*Batch, error)
|
| 115 |
GetLastClosedBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 116 |
UpdateBatchL2Data(ctx context.Context, batchNumber uint64, batchL2Data []byte, dbTx pgx.Tx) error
|
|
|
|
| 145 |
GetForkIDByBlockNumber(blockNumber uint64) uint64
|
| 146 |
GetForkIDByBatchNumber(batchNumber uint64) uint64
|
| 147 |
GetLatestIndex(ctx context.Context, dbTx pgx.Tx) (uint32, error)
|
| 148 |
+
BuildChangeL2Block(deltaTimestamp uint32, l1InfoTreeIndex uint32) []byte
|
| 149 |
GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error)
|
| 150 |
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
| 151 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
|
|
|
| 153 |
GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
| 154 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 155 |
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 156 |
+
GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error)
|
| 157 |
+
GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 158 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 159 |
GetLatestBatchGlobalExitRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error)
|
| 160 |
GetL2TxHashByTxHash(ctx context.Context, hash common.Hash, dbTx pgx.Tx) (*common.Hash, error)
|
| 161 |
GetSyncInfoData(ctx context.Context, dbTx pgx.Tx) (SyncInfoDataOnStorage, error)
|
|
|
|
| 166 |
GetNotCheckedBatches(ctx context.Context, dbTx pgx.Tx) ([]*Batch, error)
|
| 167 |
GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*L2Block, error)
|
| 168 |
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
}
|
|
@@ -1,83 +0,0 @@
|
|
| 1 |
-
package state
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
"fmt"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/l1infotree"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 10 |
-
"github.com/ethereum/go-ethereum/common"
|
| 11 |
-
"github.com/jackc/pgx/v4"
|
| 12 |
-
)
|
| 13 |
-
|
| 14 |
-
// L1InfoTreeRecursiveExitRootStorageEntry leaf of the L1InfoTreeRecursive
|
| 15 |
-
type L1InfoTreeRecursiveExitRootStorageEntry L1InfoTreeExitRootStorageEntry
|
| 16 |
-
|
| 17 |
-
func (s *State) buildL1InfoTreeRecursiveCacheIfNeed(ctx context.Context, dbTx pgx.Tx) error {
|
| 18 |
-
if s.l1InfoTreeRecursive != nil {
|
| 19 |
-
return nil
|
| 20 |
-
}
|
| 21 |
-
log.Debugf("Building L1InfoTree cache")
|
| 22 |
-
allLeaves, err := s.GetAllL1InfoTreeRecursiveRootEntries(ctx, dbTx)
|
| 23 |
-
if err != nil {
|
| 24 |
-
log.Error("error getting all leaves. Error: ", err)
|
| 25 |
-
return fmt.Errorf("error getting all leaves. Error: %w", err)
|
| 26 |
-
}
|
| 27 |
-
|
| 28 |
-
var leaves [][32]byte
|
| 29 |
-
for _, leaf := range allLeaves {
|
| 30 |
-
leaves = append(leaves, leaf.Hash())
|
| 31 |
-
}
|
| 32 |
-
mt, err := l1infotree.NewL1InfoTreeRecursiveFromLeaves(uint8(32), leaves) //nolint:gomnd
|
| 33 |
-
if err != nil {
|
| 34 |
-
log.Error("error creating L1InfoTree. Error: ", err)
|
| 35 |
-
return fmt.Errorf("error creating L1InfoTree. Error: %w", err)
|
| 36 |
-
}
|
| 37 |
-
s.l1InfoTreeRecursive = mt
|
| 38 |
-
return nil
|
| 39 |
-
}
|
| 40 |
-
|
| 41 |
-
// AddL1InfoTreeRecursiveLeaf adds a new leaf to the L1InfoTree and returns the entry and error
|
| 42 |
-
func (s *State) AddL1InfoTreeRecursiveLeaf(ctx context.Context, l1InfoTreeLeaf *L1InfoTreeLeaf, dbTx pgx.Tx) (*L1InfoTreeExitRootStorageEntry, error) {
|
| 43 |
-
var newIndex uint32
|
| 44 |
-
gerIndex, err := s.GetLatestIndex(ctx, dbTx)
|
| 45 |
-
if err != nil && !errors.Is(err, ErrNotFound) {
|
| 46 |
-
log.Error("error getting latest L1InfoTreeRecursive index. Error: ", err)
|
| 47 |
-
return nil, err
|
| 48 |
-
} else if err == nil {
|
| 49 |
-
newIndex = gerIndex + 1
|
| 50 |
-
}
|
| 51 |
-
err = s.buildL1InfoTreeCacheIfNeed(ctx, dbTx)
|
| 52 |
-
if err != nil {
|
| 53 |
-
log.Error("error building L1InfoTreeRecursive cache. Error: ", err)
|
| 54 |
-
return nil, err
|
| 55 |
-
}
|
| 56 |
-
log.Debug("latestIndex: ", gerIndex)
|
| 57 |
-
l1InfoTreeRoot, err := s.l1InfoTreeRecursive.AddLeaf(newIndex, l1InfoTreeLeaf.Hash())
|
| 58 |
-
if err != nil {
|
| 59 |
-
log.Error("error add new leaf to the L1InfoTreeRecursive. Error: ", err)
|
| 60 |
-
return nil, err
|
| 61 |
-
}
|
| 62 |
-
entry := L1InfoTreeExitRootStorageEntry{
|
| 63 |
-
L1InfoTreeLeaf: *l1InfoTreeLeaf,
|
| 64 |
-
L1InfoTreeRoot: l1InfoTreeRoot,
|
| 65 |
-
L1InfoTreeIndex: newIndex,
|
| 66 |
-
}
|
| 67 |
-
err = s.AddL1InfoRootToExitRoot(ctx, &entry, dbTx)
|
| 68 |
-
if err != nil {
|
| 69 |
-
log.Error("error adding L1InfoRoot to ExitRoot. Error: ", err)
|
| 70 |
-
return nil, err
|
| 71 |
-
}
|
| 72 |
-
return &entry, nil
|
| 73 |
-
}
|
| 74 |
-
|
| 75 |
-
// GetCurrentL1InfoTreeRecursiveRoot Return current L1InfoRoot
|
| 76 |
-
func (s *State) GetCurrentL1InfoTreeRecursiveRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error) {
|
| 77 |
-
err := s.buildL1InfoTreeRecursiveCacheIfNeed(ctx, dbTx)
|
| 78 |
-
if err != nil {
|
| 79 |
-
log.Error("error building L1InfoTree cache. Error: ", err)
|
| 80 |
-
return ZeroHash, err
|
| 81 |
-
}
|
| 82 |
-
return s.l1InfoTreeRecursive.GetRoot(), nil
|
| 83 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -45,11 +45,7 @@
|
|
| 45 |
if err != nil {
|
| 46 |
panic(err)
|
| 47 |
}
|
| 48 |
-
|
| 49 |
-
if err != nil {
|
| 50 |
-
panic(err)
|
| 51 |
-
}
|
| 52 |
-
testState := state.NewState(stateCfg, storage, nil, nil, nil, mt, mtr)
|
| 53 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 54 |
defer func() {
|
| 55 |
_ = dbTx.Rollback(ctx)
|
|
@@ -86,7 +82,7 @@
|
|
| 86 |
}},
|
| 87 |
}
|
| 88 |
ctx := context.Background()
|
| 89 |
-
testState := state.NewState(stateCfg, mockStorage, nil, nil, nil, nil
|
| 90 |
|
| 91 |
mockStorage.EXPECT().GetAllL1InfoRootEntries(ctx, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil)
|
| 92 |
|
|
@@ -112,10 +108,7 @@
|
|
| 112 |
ctx := context.Background()
|
| 113 |
l1InfoTree, err := l1infotree.NewL1InfoTree(uint8(32), nil)
|
| 114 |
require.NoError(t, err)
|
| 115 |
-
|
| 116 |
-
l1InfoTreeRecursive, err := l1infotree.NewL1InfoTreeRecursive(32)
|
| 117 |
-
require.NoError(t, err)
|
| 118 |
-
testState := state.NewState(stateCfg, mockStorage, nil, nil, nil, l1InfoTree, l1InfoTreeRecursive)
|
| 119 |
|
| 120 |
// GetCurrentL1InfoRoot use the cache value in state.l1InfoTree
|
| 121 |
l1InfoRoot, err := testState.GetCurrentL1InfoRoot(ctx, nil)
|
|
@@ -138,7 +131,7 @@
|
|
| 138 |
}},
|
| 139 |
}
|
| 140 |
ctx := context.Background()
|
| 141 |
-
testState := state.NewState(stateCfg, mockStorage, nil, nil, nil, nil
|
| 142 |
|
| 143 |
mockStorage.EXPECT().GetLatestIndex(ctx, mock.Anything).Return(uint32(0), state.ErrNotFound)
|
| 144 |
mockStorage.EXPECT().AddL1InfoRootToExitRoot(ctx, mock.Anything, mock.Anything).Return(nil)
|
|
|
|
| 45 |
if err != nil {
|
| 46 |
panic(err)
|
| 47 |
}
|
| 48 |
+
testState := state.NewState(stateCfg, storage, nil, nil, nil, mt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 50 |
defer func() {
|
| 51 |
_ = dbTx.Rollback(ctx)
|
|
|
|
| 82 |
}},
|
| 83 |
}
|
| 84 |
ctx := context.Background()
|
| 85 |
+
testState := state.NewState(stateCfg, mockStorage, nil, nil, nil, nil)
|
| 86 |
|
| 87 |
mockStorage.EXPECT().GetAllL1InfoRootEntries(ctx, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil)
|
| 88 |
|
|
|
|
| 108 |
ctx := context.Background()
|
| 109 |
l1InfoTree, err := l1infotree.NewL1InfoTree(uint8(32), nil)
|
| 110 |
require.NoError(t, err)
|
| 111 |
+
testState := state.NewState(stateCfg, mockStorage, nil, nil, nil, l1InfoTree)
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
// GetCurrentL1InfoRoot use the cache value in state.l1InfoTree
|
| 114 |
l1InfoRoot, err := testState.GetCurrentL1InfoRoot(ctx, nil)
|
|
|
|
| 131 |
}},
|
| 132 |
}
|
| 133 |
ctx := context.Background()
|
| 134 |
+
testState := state.NewState(stateCfg, mockStorage, nil, nil, nil, nil)
|
| 135 |
|
| 136 |
mockStorage.EXPECT().GetLatestIndex(ctx, mock.Anything).Return(uint32(0), state.ErrNotFound)
|
| 137 |
mockStorage.EXPECT().AddL1InfoRootToExitRoot(ctx, mock.Anything, mock.Anything).Return(nil)
|
|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
|
|
|
| 5 |
"encoding/json"
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
|
@@ -785,7 +786,7 @@
|
|
| 785 |
b.batch_num > $1 AND b.batch_num = v.batch_num AND
|
| 786 |
v.block_num <= $2 AND
|
| 787 |
NOT EXISTS (
|
| 788 |
-
SELECT p.batch_num FROM state.
|
| 789 |
WHERE v.batch_num >= p.batch_num AND v.batch_num <= p.batch_num_final
|
| 790 |
)
|
| 791 |
ORDER BY b.batch_num ASC LIMIT 1
|
|
@@ -956,6 +957,25 @@
|
|
| 956 |
return blockNum, nil
|
| 957 |
}
|
| 958 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 959 |
// GetRawBatchTimestamps returns the timestamp of the batch with the given number.
|
| 960 |
// it returns batch_num.tstamp and virtual_batch.batch_timestamp
|
| 961 |
func (p *PostgresStorage) GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error) {
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
+
"encoding/binary"
|
| 6 |
"encoding/json"
|
| 7 |
"errors"
|
| 8 |
"fmt"
|
|
|
|
| 786 |
b.batch_num > $1 AND b.batch_num = v.batch_num AND
|
| 787 |
v.block_num <= $2 AND
|
| 788 |
NOT EXISTS (
|
| 789 |
+
SELECT p.batch_num FROM state.proof p
|
| 790 |
WHERE v.batch_num >= p.batch_num AND v.batch_num <= p.batch_num_final
|
| 791 |
)
|
| 792 |
ORDER BY b.batch_num ASC LIMIT 1
|
|
|
|
| 957 |
return blockNum, nil
|
| 958 |
}
|
| 959 |
|
| 960 |
+
// BuildChangeL2Block returns a changeL2Block tx to use in the BatchL2Data
|
| 961 |
+
func (p *PostgresStorage) BuildChangeL2Block(deltaTimestamp uint32, l1InfoTreeIndex uint32) []byte {
|
| 962 |
+
changeL2BlockMark := []byte{0x0B}
|
| 963 |
+
changeL2Block := []byte{}
|
| 964 |
+
|
| 965 |
+
// changeL2Block transaction mark
|
| 966 |
+
changeL2Block = append(changeL2Block, changeL2BlockMark...)
|
| 967 |
+
// changeL2Block deltaTimeStamp
|
| 968 |
+
deltaTimestampBytes := make([]byte, 4) //nolint:gomnd
|
| 969 |
+
binary.BigEndian.PutUint32(deltaTimestampBytes, deltaTimestamp)
|
| 970 |
+
changeL2Block = append(changeL2Block, deltaTimestampBytes...)
|
| 971 |
+
// changeL2Block l1InfoTreeIndexBytes
|
| 972 |
+
l1InfoTreeIndexBytes := make([]byte, 4) //nolint:gomnd
|
| 973 |
+
binary.BigEndian.PutUint32(l1InfoTreeIndexBytes, l1InfoTreeIndex)
|
| 974 |
+
changeL2Block = append(changeL2Block, l1InfoTreeIndexBytes...)
|
| 975 |
+
|
| 976 |
+
return changeL2Block
|
| 977 |
+
}
|
| 978 |
+
|
| 979 |
// GetRawBatchTimestamps returns the timestamp of the batch with the given number.
|
| 980 |
// it returns batch_num.tstamp and virtual_batch.batch_timestamp
|
| 981 |
func (p *PostgresStorage) GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error) {
|
|
@@ -1 +0,0 @@
|
|
| 1 |
-
package pgstatestorage
|
|
|
|
|
|
|
@@ -1,41 +0,0 @@
|
|
| 1 |
-
package pgstatestorage
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"time"
|
| 6 |
-
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 8 |
-
"github.com/ethereum/go-ethereum/common"
|
| 9 |
-
"github.com/jackc/pgx/v4"
|
| 10 |
-
)
|
| 11 |
-
|
| 12 |
-
const blobInnerFields = "blob_sequence_index, blob_inner_num, blob_type, max_sequence_timestamp, zk_gas_limit, l1_info_tree_leaf_index, l1_info_tree_root,blob_data_hash, updated_at"
|
| 13 |
-
const blobInnerFieldsTypeBlob = "blob_type_index,blob_type_z, blob_type_y,blob_type_commitment,blob_type_proof"
|
| 14 |
-
|
| 15 |
-
func (p *PostgresStorage) AddBlobInner(ctx context.Context, blobInner *state.BlobInner, dbTx pgx.Tx) error {
|
| 16 |
-
sql := "INSERT INTO state.blob_inner_in (" + blobInnerFields
|
| 17 |
-
if blobInner.Type == state.TypeBlobTransaction {
|
| 18 |
-
sql += "," + blobInnerFieldsTypeBlob
|
| 19 |
-
}
|
| 20 |
-
sql += ") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9"
|
| 21 |
-
if blobInner.Type == state.TypeBlobTransaction {
|
| 22 |
-
sql += ",$10,$11,$12,$13,$14"
|
| 23 |
-
}
|
| 24 |
-
sql += ")"
|
| 25 |
-
e := p.getExecQuerier(dbTx)
|
| 26 |
-
arguments := []interface{}{blobInner.BlobSequenceIndex, blobInner.BlobInnerNum, blobInner.Type.String(), blobInner.MaxSequenceTimestamp, blobInner.ZkGasLimit, blobInner.L1InfoLeafIndex, blobInner.L1InfoTreeRoot.String(), blobInner.BlobDataHash.String(), time.Now()}
|
| 27 |
-
if blobInner.Type == state.TypeBlobTransaction {
|
| 28 |
-
commitment, err := blobInner.BlobBlobTypeParams.Commitment.MarshalText()
|
| 29 |
-
if err != nil {
|
| 30 |
-
return err
|
| 31 |
-
}
|
| 32 |
-
proof, err := blobInner.BlobBlobTypeParams.Proof.MarshalText()
|
| 33 |
-
if err != nil {
|
| 34 |
-
return err
|
| 35 |
-
}
|
| 36 |
-
arguments = append(arguments, blobInner.BlobBlobTypeParams.BlobIndex, common.Bytes2Hex(blobInner.BlobBlobTypeParams.Z), common.Bytes2Hex(blobInner.BlobBlobTypeParams.Y), commitment, proof)
|
| 37 |
-
}
|
| 38 |
-
_, err := e.Exec(ctx, sql, arguments...)
|
| 39 |
-
return err
|
| 40 |
-
|
| 41 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,48 +0,0 @@
|
|
| 1 |
-
package pgstatestorage
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
"time"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
-
"github.com/ethereum/go-ethereum/common"
|
| 10 |
-
"github.com/jackc/pgx/v4"
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
// AddBlobSequence adds a new blob sequence to the state.
|
| 14 |
-
// TODO: Add support to ReceivedAt
|
| 15 |
-
func (p *PostgresStorage) AddBlobSequence(ctx context.Context, blobSequence *state.BlobSequence, dbTx pgx.Tx) error {
|
| 16 |
-
const addBlobSequenceSQL = "INSERT INTO state.blob_sequence (index, block_num, coinbase, final_acc_input_hash, first_blob_sequenced, last_blob_sequenced, created_at) VALUES ($1, $2, $3, $4, $5, $6, $7)"
|
| 17 |
-
|
| 18 |
-
e := p.getExecQuerier(dbTx)
|
| 19 |
-
_, err := e.Exec(ctx, addBlobSequenceSQL, blobSequence.BlobSequenceIndex, blobSequence.BlockNumber, blobSequence.L2Coinbase.String(), blobSequence.FinalAccInputHash.String(), blobSequence.FirstBlobSequenced, blobSequence.LastBlobSequenced, blobSequence.CreateAt)
|
| 20 |
-
return err
|
| 21 |
-
}
|
| 22 |
-
|
| 23 |
-
// GetLastBlobSequence returns the last blob sequence stored in the state.
|
| 24 |
-
// TODO: Add support to ReceivedAt
|
| 25 |
-
func (p *PostgresStorage) GetLastBlobSequence(ctx context.Context, dbTx pgx.Tx) (*state.BlobSequence, error) {
|
| 26 |
-
var (
|
| 27 |
-
coinbase string
|
| 28 |
-
finalAccInputHash string
|
| 29 |
-
createAt time.Time
|
| 30 |
-
blobSequence state.BlobSequence
|
| 31 |
-
)
|
| 32 |
-
const getLastBlobSequenceSQL = "SELECT index, coinbase, final_acc_input_hash, first_blob_sequenced, last_blob_sequenced, created_at FROM state.blob_sequence ORDER BY index DESC LIMIT 1"
|
| 33 |
-
|
| 34 |
-
q := p.getExecQuerier(dbTx)
|
| 35 |
-
|
| 36 |
-
err := q.QueryRow(ctx, getLastBlobSequenceSQL).Scan(&blobSequence.BlobSequenceIndex, &coinbase, &finalAccInputHash, &blobSequence.FirstBlobSequenced, &blobSequence.LastBlobSequenced, &createAt)
|
| 37 |
-
if errors.Is(err, pgx.ErrNoRows) {
|
| 38 |
-
// If none on database return a nil object
|
| 39 |
-
return nil, nil
|
| 40 |
-
}
|
| 41 |
-
if err != nil {
|
| 42 |
-
return nil, err
|
| 43 |
-
}
|
| 44 |
-
blobSequence.L2Coinbase = common.HexToAddress(coinbase)
|
| 45 |
-
blobSequence.FinalAccInputHash = common.HexToHash(finalAccInputHash)
|
| 46 |
-
blobSequence.CreateAt = createAt
|
| 47 |
-
return &blobSequence, nil
|
| 48 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -17,7 +17,7 @@
|
|
| 17 |
panic(err)
|
| 18 |
}
|
| 19 |
pgStateStorage = pgstatestorage.NewPostgresStorage(state.Config{}, stateDb)
|
| 20 |
-
testState = state.NewState(stateCfg, pgStateStorage, executorClient, stateTree, nil, nil
|
| 21 |
|
| 22 |
for i := 1; i <= 6; i++ {
|
| 23 |
err = testState.AddForkID(ctx, state.ForkIDInterval{ForkId: uint64(i), BlockNumber: uint64(i * 100), FromBatchNumber: uint64(i * 10), ToBatchNumber: uint64(i*10) + 9}, nil)
|
|
@@ -76,13 +76,13 @@
|
|
| 76 |
panic(err)
|
| 77 |
}
|
| 78 |
pgStateStorage = pgstatestorage.NewPostgresStorage(stateCfg, stateDb)
|
| 79 |
-
testState = state.NewState(stateCfg, pgStateStorage, executorClient, stateTree, nil, nil
|
| 80 |
-
st := state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), executorClient, stateTree, nil, nil
|
| 81 |
|
| 82 |
avoidMemoryStateCfg := stateCfg
|
| 83 |
avoidMemoryStateCfg.AvoidForkIDInMemory = true
|
| 84 |
pgStateStorageAvoidMemory := pgstatestorage.NewPostgresStorage(avoidMemoryStateCfg, stateDb)
|
| 85 |
-
stAvoidMemory := state.NewState(avoidMemoryStateCfg, pgStateStorageAvoidMemory, executorClient, stateTree, nil, nil
|
| 86 |
|
| 87 |
// persist forkID intervals
|
| 88 |
forkIdIntervals := []state.ForkIDInterval{}
|
|
|
|
| 17 |
panic(err)
|
| 18 |
}
|
| 19 |
pgStateStorage = pgstatestorage.NewPostgresStorage(state.Config{}, stateDb)
|
| 20 |
+
testState = state.NewState(stateCfg, pgStateStorage, executorClient, stateTree, nil, nil)
|
| 21 |
|
| 22 |
for i := 1; i <= 6; i++ {
|
| 23 |
err = testState.AddForkID(ctx, state.ForkIDInterval{ForkId: uint64(i), BlockNumber: uint64(i * 100), FromBatchNumber: uint64(i * 10), ToBatchNumber: uint64(i*10) + 9}, nil)
|
|
|
|
| 76 |
panic(err)
|
| 77 |
}
|
| 78 |
pgStateStorage = pgstatestorage.NewPostgresStorage(stateCfg, stateDb)
|
| 79 |
+
testState = state.NewState(stateCfg, pgStateStorage, executorClient, stateTree, nil, nil)
|
| 80 |
+
st := state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), executorClient, stateTree, nil, nil)
|
| 81 |
|
| 82 |
avoidMemoryStateCfg := stateCfg
|
| 83 |
avoidMemoryStateCfg.AvoidForkIDInMemory = true
|
| 84 |
pgStateStorageAvoidMemory := pgstatestorage.NewPostgresStorage(avoidMemoryStateCfg, stateDb)
|
| 85 |
+
stAvoidMemory := state.NewState(avoidMemoryStateCfg, pgStateStorageAvoidMemory, executorClient, stateTree, nil, nil)
|
| 86 |
|
| 87 |
// persist forkID intervals
|
| 88 |
forkIdIntervals := []state.ForkIDInterval{}
|
|
@@ -93,7 +93,7 @@
|
|
| 93 |
}
|
| 94 |
storage := NewPostgresStorage(cfg, nil)
|
| 95 |
// Create a new State instance with test data
|
| 96 |
-
state := state.NewState(cfg, storage, nil, nil, nil, nil
|
| 97 |
|
| 98 |
// Call the function being tested
|
| 99 |
actual := state.GetForkIDByBlockNumber(tc.blockNumber)
|
|
|
|
| 93 |
}
|
| 94 |
storage := NewPostgresStorage(cfg, nil)
|
| 95 |
// Create a new State instance with test data
|
| 96 |
+
state := state.NewState(cfg, storage, nil, nil, nil, nil)
|
| 97 |
|
| 98 |
// Call the function being tested
|
| 99 |
actual := state.GetForkIDByBlockNumber(tc.blockNumber)
|
|
@@ -3,48 +3,33 @@
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
| 6 |
-
"fmt"
|
| 7 |
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
"github.com/ethereum/go-ethereum/common"
|
| 10 |
"github.com/jackc/pgx/v4"
|
| 11 |
)
|
| 12 |
|
| 13 |
-
const (
|
| 14 |
-
l1InfoTreeIndexFieldName = "l1_info_tree_index"
|
| 15 |
-
)
|
| 16 |
-
|
| 17 |
// AddL1InfoRootToExitRoot adds a new entry in ExitRoot and returns index of L1InfoTree and error
|
| 18 |
func (p *PostgresStorage) AddL1InfoRootToExitRoot(ctx context.Context, exitRoot *state.L1InfoTreeExitRootStorageEntry, dbTx pgx.Tx) error {
|
| 19 |
-
return p.addL1InfoRootToExitRootVx(ctx, exitRoot, dbTx, l1InfoTreeIndexFieldName)
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
func (p *PostgresStorage) addL1InfoRootToExitRootVx(ctx context.Context, exitRoot *state.L1InfoTreeExitRootStorageEntry, dbTx pgx.Tx, indexFieldName string) error {
|
| 23 |
const addGlobalExitRootSQL = `
|
| 24 |
-
INSERT INTO state.exit_root(block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root,
|
| 25 |
VALUES ($1, $2, $3, $4, $5, $6, $7, $8);
|
| 26 |
`
|
| 27 |
-
sql := fmt.Sprintf(addGlobalExitRootSQL, indexFieldName)
|
| 28 |
e := p.getExecQuerier(dbTx)
|
| 29 |
-
_, err := e.Exec(ctx,
|
| 30 |
exitRoot.BlockNumber, exitRoot.Timestamp, exitRoot.MainnetExitRoot, exitRoot.RollupExitRoot,
|
| 31 |
exitRoot.GlobalExitRoot.GlobalExitRoot, exitRoot.PreviousBlockHash, exitRoot.L1InfoTreeRoot, exitRoot.L1InfoTreeIndex)
|
| 32 |
return err
|
| 33 |
}
|
| 34 |
|
| 35 |
func (p *PostgresStorage) GetAllL1InfoRootEntries(ctx context.Context, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) {
|
| 36 |
-
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
func (p *PostgresStorage) GetAllL1InfoRootEntriesVx(ctx context.Context, dbTx pgx.Tx, indexFieldName string) ([]state.L1InfoTreeExitRootStorageEntry, error) {
|
| 40 |
-
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, %s
|
| 41 |
FROM state.exit_root
|
| 42 |
-
WHERE
|
| 43 |
-
ORDER BY
|
| 44 |
|
| 45 |
-
sql := fmt.Sprintf(getL1InfoRootSQL, indexFieldName, indexFieldName, indexFieldName)
|
| 46 |
e := p.getExecQuerier(dbTx)
|
| 47 |
-
rows, err := e.Query(ctx,
|
| 48 |
if err != nil {
|
| 49 |
return nil, err
|
| 50 |
}
|
|
@@ -65,22 +50,15 @@
|
|
| 65 |
|
| 66 |
// GetLatestL1InfoRoot is used to get the latest L1InfoRoot
|
| 67 |
func (p *PostgresStorage) GetLatestL1InfoRoot(ctx context.Context, maxBlockNumber uint64) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 68 |
-
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
// GetLatestL1InfoRoot is used to get the latest L1InfoRoot
|
| 72 |
-
func (p *PostgresStorage) GetLatestL1InfoRootVx(ctx context.Context, maxBlockNumber uint64, dbTx pgx.Tx, indexFieldName string) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 73 |
-
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, %s
|
| 74 |
FROM state.exit_root
|
| 75 |
-
WHERE
|
| 76 |
-
ORDER BY
|
| 77 |
-
|
| 78 |
-
sql := fmt.Sprintf(getL1InfoRootSQL, indexFieldName, indexFieldName, indexFieldName)
|
| 79 |
|
| 80 |
entry := state.L1InfoTreeExitRootStorageEntry{}
|
| 81 |
|
| 82 |
-
e := p.getExecQuerier(
|
| 83 |
-
err := e.QueryRow(ctx,
|
| 84 |
&entry.PreviousBlockHash, &entry.L1InfoTreeRoot, &entry.L1InfoTreeIndex)
|
| 85 |
|
| 86 |
if !errors.Is(err, pgx.ErrNoRows) {
|
|
@@ -90,16 +68,11 @@
|
|
| 90 |
return entry, nil
|
| 91 |
}
|
| 92 |
func (p *PostgresStorage) GetLatestIndex(ctx context.Context, dbTx pgx.Tx) (uint32, error) {
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
func (p *PostgresStorage) GetLatestIndexVx(ctx context.Context, dbTx pgx.Tx, indexFieldName string) (uint32, error) {
|
| 96 |
-
const getLatestIndexSQL = `SELECT max(%s) as %s FROM state.exit_root
|
| 97 |
-
WHERE %s IS NOT NULL`
|
| 98 |
-
sql := fmt.Sprintf(getLatestIndexSQL, indexFieldName, indexFieldName, indexFieldName)
|
| 99 |
-
|
| 100 |
var l1InfoTreeIndex *uint32
|
| 101 |
e := p.getExecQuerier(dbTx)
|
| 102 |
-
err := e.QueryRow(ctx,
|
| 103 |
if err != nil {
|
| 104 |
return 0, err
|
| 105 |
}
|
|
@@ -110,17 +83,13 @@
|
|
| 110 |
}
|
| 111 |
|
| 112 |
func (p *PostgresStorage) GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 113 |
-
|
| 114 |
-
}
|
| 115 |
-
|
| 116 |
-
func (p *PostgresStorage) GetL1InfoRootLeafByL1InfoRootVx(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx, indexFieldName string) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 117 |
-
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, %s
|
| 118 |
FROM state.exit_root
|
| 119 |
-
WHERE
|
| 120 |
-
|
| 121 |
var entry state.L1InfoTreeExitRootStorageEntry
|
| 122 |
e := p.getExecQuerier(dbTx)
|
| 123 |
-
err := e.QueryRow(ctx,
|
| 124 |
&entry.PreviousBlockHash, &entry.L1InfoTreeRoot, &entry.L1InfoTreeIndex)
|
| 125 |
if !errors.Is(err, pgx.ErrNoRows) {
|
| 126 |
return entry, err
|
|
@@ -129,17 +98,13 @@
|
|
| 129 |
}
|
| 130 |
|
| 131 |
func (p *PostgresStorage) GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 132 |
-
|
| 133 |
-
}
|
| 134 |
-
|
| 135 |
-
func (p *PostgresStorage) GetL1InfoRootLeafByIndexVx(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx, indexFieldName string) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 136 |
-
const getL1InfoRootByIndexSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, %s
|
| 137 |
FROM state.exit_root
|
| 138 |
-
WHERE
|
| 139 |
-
|
| 140 |
var entry state.L1InfoTreeExitRootStorageEntry
|
| 141 |
e := p.getExecQuerier(dbTx)
|
| 142 |
-
err := e.QueryRow(ctx,
|
| 143 |
&entry.PreviousBlockHash, &entry.L1InfoTreeRoot, &entry.L1InfoTreeIndex)
|
| 144 |
if !errors.Is(err, pgx.ErrNoRows) {
|
| 145 |
return entry, err
|
|
@@ -148,18 +113,14 @@
|
|
| 148 |
}
|
| 149 |
|
| 150 |
func (p *PostgresStorage) GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) {
|
| 151 |
-
return p.GetLeavesByL1InfoRootVx(ctx, l1InfoRoot, dbTx, l1InfoTreeIndexFieldName)
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
func (p *PostgresStorage) GetLeavesByL1InfoRootVx(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx, indexFieldName string) ([]state.L1InfoTreeExitRootStorageEntry, error) {
|
| 155 |
// TODO: Optimize this query
|
| 156 |
-
const
|
| 157 |
FROM state.exit_root
|
| 158 |
-
WHERE
|
| 159 |
-
ORDER BY
|
| 160 |
-
|
| 161 |
e := p.getExecQuerier(dbTx)
|
| 162 |
-
rows, err := e.Query(ctx,
|
| 163 |
if err != nil {
|
| 164 |
return nil, err
|
| 165 |
}
|
|
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
|
|
|
| 6 |
|
| 7 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 8 |
"github.com/ethereum/go-ethereum/common"
|
| 9 |
"github.com/jackc/pgx/v4"
|
| 10 |
)
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
// AddL1InfoRootToExitRoot adds a new entry in ExitRoot and returns index of L1InfoTree and error
|
| 13 |
func (p *PostgresStorage) AddL1InfoRootToExitRoot(ctx context.Context, exitRoot *state.L1InfoTreeExitRootStorageEntry, dbTx pgx.Tx) error {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
const addGlobalExitRootSQL = `
|
| 15 |
+
INSERT INTO state.exit_root(block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index)
|
| 16 |
VALUES ($1, $2, $3, $4, $5, $6, $7, $8);
|
| 17 |
`
|
|
|
|
| 18 |
e := p.getExecQuerier(dbTx)
|
| 19 |
+
_, err := e.Exec(ctx, addGlobalExitRootSQL,
|
| 20 |
exitRoot.BlockNumber, exitRoot.Timestamp, exitRoot.MainnetExitRoot, exitRoot.RollupExitRoot,
|
| 21 |
exitRoot.GlobalExitRoot.GlobalExitRoot, exitRoot.PreviousBlockHash, exitRoot.L1InfoTreeRoot, exitRoot.L1InfoTreeIndex)
|
| 22 |
return err
|
| 23 |
}
|
| 24 |
|
| 25 |
func (p *PostgresStorage) GetAllL1InfoRootEntries(ctx context.Context, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) {
|
| 26 |
+
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
FROM state.exit_root
|
| 28 |
+
WHERE l1_info_tree_index IS NOT NULL
|
| 29 |
+
ORDER BY l1_info_tree_index`
|
| 30 |
|
|
|
|
| 31 |
e := p.getExecQuerier(dbTx)
|
| 32 |
+
rows, err := e.Query(ctx, getL1InfoRootSQL)
|
| 33 |
if err != nil {
|
| 34 |
return nil, err
|
| 35 |
}
|
|
|
|
| 50 |
|
| 51 |
// GetLatestL1InfoRoot is used to get the latest L1InfoRoot
|
| 52 |
func (p *PostgresStorage) GetLatestL1InfoRoot(ctx context.Context, maxBlockNumber uint64) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 53 |
+
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
FROM state.exit_root
|
| 55 |
+
WHERE l1_info_tree_index IS NOT NULL AND block_num <= $1
|
| 56 |
+
ORDER BY l1_info_tree_index DESC LIMIT 1`
|
|
|
|
|
|
|
| 57 |
|
| 58 |
entry := state.L1InfoTreeExitRootStorageEntry{}
|
| 59 |
|
| 60 |
+
e := p.getExecQuerier(nil)
|
| 61 |
+
err := e.QueryRow(ctx, getL1InfoRootSQL, maxBlockNumber).Scan(&entry.BlockNumber, &entry.Timestamp, &entry.MainnetExitRoot, &entry.RollupExitRoot, &entry.GlobalExitRoot.GlobalExitRoot,
|
| 62 |
&entry.PreviousBlockHash, &entry.L1InfoTreeRoot, &entry.L1InfoTreeIndex)
|
| 63 |
|
| 64 |
if !errors.Is(err, pgx.ErrNoRows) {
|
|
|
|
| 68 |
return entry, nil
|
| 69 |
}
|
| 70 |
func (p *PostgresStorage) GetLatestIndex(ctx context.Context, dbTx pgx.Tx) (uint32, error) {
|
| 71 |
+
const getLatestIndexSQL = `SELECT max(l1_info_tree_index) as l1_info_tree_index FROM state.exit_root
|
| 72 |
+
WHERE l1_info_tree_index IS NOT NULL`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
var l1InfoTreeIndex *uint32
|
| 74 |
e := p.getExecQuerier(dbTx)
|
| 75 |
+
err := e.QueryRow(ctx, getLatestIndexSQL).Scan(&l1InfoTreeIndex)
|
| 76 |
if err != nil {
|
| 77 |
return 0, err
|
| 78 |
}
|
|
|
|
| 83 |
}
|
| 84 |
|
| 85 |
func (p *PostgresStorage) GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 86 |
+
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
FROM state.exit_root
|
| 88 |
+
WHERE l1_info_tree_index IS NOT NULL AND l1_info_root=$1`
|
| 89 |
+
|
| 90 |
var entry state.L1InfoTreeExitRootStorageEntry
|
| 91 |
e := p.getExecQuerier(dbTx)
|
| 92 |
+
err := e.QueryRow(ctx, getL1InfoRootSQL, l1InfoRoot).Scan(&entry.BlockNumber, &entry.Timestamp, &entry.MainnetExitRoot, &entry.RollupExitRoot, &entry.GlobalExitRoot.GlobalExitRoot,
|
| 93 |
&entry.PreviousBlockHash, &entry.L1InfoTreeRoot, &entry.L1InfoTreeIndex)
|
| 94 |
if !errors.Is(err, pgx.ErrNoRows) {
|
| 95 |
return entry, err
|
|
|
|
| 98 |
}
|
| 99 |
|
| 100 |
func (p *PostgresStorage) GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 101 |
+
const getL1InfoRootByIndexSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
FROM state.exit_root
|
| 103 |
+
WHERE l1_info_tree_index = $1`
|
| 104 |
+
|
| 105 |
var entry state.L1InfoTreeExitRootStorageEntry
|
| 106 |
e := p.getExecQuerier(dbTx)
|
| 107 |
+
err := e.QueryRow(ctx, getL1InfoRootByIndexSQL, l1InfoTreeIndex).Scan(&entry.BlockNumber, &entry.Timestamp, &entry.MainnetExitRoot, &entry.RollupExitRoot, &entry.GlobalExitRoot.GlobalExitRoot,
|
| 108 |
&entry.PreviousBlockHash, &entry.L1InfoTreeRoot, &entry.L1InfoTreeIndex)
|
| 109 |
if !errors.Is(err, pgx.ErrNoRows) {
|
| 110 |
return entry, err
|
|
|
|
| 113 |
}
|
| 114 |
|
| 115 |
func (p *PostgresStorage) GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
// TODO: Optimize this query
|
| 117 |
+
const getLeafsByL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
| 118 |
FROM state.exit_root
|
| 119 |
+
WHERE l1_info_tree_index IS NOT NULL AND l1_info_tree_index <= (SELECT l1_info_tree_index FROM state.exit_root WHERE l1_info_root=$1)
|
| 120 |
+
ORDER BY l1_info_tree_index ASC`
|
| 121 |
+
|
| 122 |
e := p.getExecQuerier(dbTx)
|
| 123 |
+
rows, err := e.Query(ctx, getLeafsByL1InfoRootSQL, l1InfoRoot)
|
| 124 |
if err != nil {
|
| 125 |
return nil, err
|
| 126 |
}
|
|
@@ -1,46 +0,0 @@
|
|
| 1 |
-
package pgstatestorage
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
|
| 6 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 7 |
-
"github.com/jackc/pgx/v4"
|
| 8 |
-
)
|
| 9 |
-
|
| 10 |
-
const (
|
| 11 |
-
l1InfoTreeRecursiveIndexFieldName = "l1_info_tree_recursive_index"
|
| 12 |
-
)
|
| 13 |
-
|
| 14 |
-
// AddL1InfoRootToExitRoot adds a new entry in ExitRoot and returns index of L1InfoTree and error
|
| 15 |
-
func (p *PostgresStorage) AddL1InfoTreeRecursiveRootToExitRoot(ctx context.Context, exitRoot *state.L1InfoTreeRecursiveExitRootStorageEntry, dbTx pgx.Tx) error {
|
| 16 |
-
exitRootOld := state.L1InfoTreeExitRootStorageEntry(*exitRoot)
|
| 17 |
-
return p.addL1InfoRootToExitRootVx(ctx, &exitRootOld, dbTx, l1InfoTreeRecursiveIndexFieldName)
|
| 18 |
-
}
|
| 19 |
-
|
| 20 |
-
func (p *PostgresStorage) GetAllL1InfoTreeRecursiveRootEntries(ctx context.Context, dbTx pgx.Tx) ([]state.L1InfoTreeRecursiveExitRootStorageEntry, error) {
|
| 21 |
-
res, err := p.GetAllL1InfoRootEntriesVx(ctx, dbTx, l1InfoTreeRecursiveIndexFieldName)
|
| 22 |
-
if err != nil {
|
| 23 |
-
return nil, err
|
| 24 |
-
}
|
| 25 |
-
var entries []state.L1InfoTreeRecursiveExitRootStorageEntry
|
| 26 |
-
for _, entry := range res {
|
| 27 |
-
entries = append(entries, state.L1InfoTreeRecursiveExitRootStorageEntry(entry))
|
| 28 |
-
}
|
| 29 |
-
return entries, nil
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
func (p *PostgresStorage) GetLatestL1InfoTreeRecursiveRoot(ctx context.Context, maxBlockNumber uint64, dbTx pgx.Tx) (state.L1InfoTreeRecursiveExitRootStorageEntry, error) {
|
| 33 |
-
res, err := p.GetLatestL1InfoRootVx(ctx, maxBlockNumber, dbTx, l1InfoTreeRecursiveIndexFieldName)
|
| 34 |
-
if err != nil {
|
| 35 |
-
return state.L1InfoTreeRecursiveExitRootStorageEntry{}, err
|
| 36 |
-
}
|
| 37 |
-
return state.L1InfoTreeRecursiveExitRootStorageEntry(res), nil
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
func (p *PostgresStorage) GetLatestL1InfoTreeRecursiveIndex(ctx context.Context, dbTx pgx.Tx) (uint32, error) {
|
| 41 |
-
return p.GetLatestIndexVx(ctx, dbTx, l1InfoTreeRecursiveIndexFieldName)
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
func (p *PostgresStorage) GetL1InfoRecursiveRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error) {
|
| 45 |
-
return p.GetL1InfoRootLeafByIndexVx(ctx, l1InfoTreeIndex, dbTx, l1InfoTreeIndexFieldName)
|
| 46 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -355,3 +355,87 @@
|
|
| 355 |
}
|
| 356 |
return nativeBlockHashes, nil
|
| 357 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
}
|
| 356 |
return nativeBlockHashes, nil
|
| 357 |
}
|
| 358 |
+
|
| 359 |
+
// GetBatchL2DataByNumber returns the batch L2 data of the given batch number.
|
| 360 |
+
func (p *PostgresStorage) GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error) {
|
| 361 |
+
batchData, err := p.GetBatchL2DataByNumbers(ctx, []uint64{batchNumber}, dbTx)
|
| 362 |
+
if err != nil {
|
| 363 |
+
return nil, err
|
| 364 |
+
}
|
| 365 |
+
data, ok := batchData[batchNumber]
|
| 366 |
+
if !ok {
|
| 367 |
+
return nil, state.ErrNotFound
|
| 368 |
+
}
|
| 369 |
+
return data, nil
|
| 370 |
+
}
|
| 371 |
+
|
| 372 |
+
// GetBatchL2DataByNumbers returns the batch L2 data of the given batch numbers. The data is a union of state.batch and state.forced_batch tables.
|
| 373 |
+
func (p *PostgresStorage) GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 374 |
+
const sql = "SELECT batch_num, raw_txs_data FROM state.batch WHERE batch_num = ANY($1)"
|
| 375 |
+
return p.getBatchData(ctx, sql, batchNumbers, dbTx)
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
// GetForcedBatchDataByNumbers returns the forced batch data of the given batch numbers
|
| 379 |
+
func (p *PostgresStorage) GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 380 |
+
const sql = "SELECT forced_batch_num, convert_from(decode(raw_txs_data, 'hex'), 'UTF8')::bytea FROM state.forced_batch WHERE forced_batch_num = ANY($1)"
|
| 381 |
+
return p.getBatchData(ctx, sql, batchNumbers, dbTx)
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
func (p *PostgresStorage) getBatchData(ctx context.Context, sql string, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 385 |
+
q := p.getExecQuerier(dbTx)
|
| 386 |
+
rows, err := q.Query(ctx, sql, batchNumbers)
|
| 387 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 388 |
+
return p.GetBatchL2DataByNumbersFromBackup(ctx, batchNumbers, dbTx)
|
| 389 |
+
} else if err != nil {
|
| 390 |
+
return nil, err
|
| 391 |
+
}
|
| 392 |
+
defer rows.Close()
|
| 393 |
+
|
| 394 |
+
batchL2DataMap, err := readBatchDataResults(rows, batchNumbers)
|
| 395 |
+
if err != nil {
|
| 396 |
+
return nil, err
|
| 397 |
+
}
|
| 398 |
+
|
| 399 |
+
if len(batchL2DataMap) == 0 {
|
| 400 |
+
return p.GetBatchL2DataByNumbersFromBackup(ctx, batchNumbers, dbTx)
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
return batchL2DataMap, nil
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
// GetBatchL2DataByNumbersFromBackup returns the batch L2 data of the given batch number from the backup table
|
| 407 |
+
func (p *PostgresStorage) GetBatchL2DataByNumbersFromBackup(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 408 |
+
getBatchL2DataByBatchNumber := `
|
| 409 |
+
SELECT batch_num, data FROM state.batch_data_backup
|
| 410 |
+
WHERE batch_num = ANY($1)
|
| 411 |
+
ORDER BY created_at DESC
|
| 412 |
+
`
|
| 413 |
+
q := p.getExecQuerier(dbTx)
|
| 414 |
+
rows, err := q.Query(ctx, getBatchL2DataByBatchNumber, batchNumbers)
|
| 415 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 416 |
+
return nil, state.ErrNotFound
|
| 417 |
+
} else if err != nil {
|
| 418 |
+
return nil, err
|
| 419 |
+
}
|
| 420 |
+
defer rows.Close()
|
| 421 |
+
|
| 422 |
+
return readBatchDataResults(rows, batchNumbers)
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
// readBatchDataResults retrieves batch data from the provided result set
|
| 426 |
+
func readBatchDataResults(results pgx.Rows, batchNumbers []uint64) (map[uint64][]byte, error) {
|
| 427 |
+
batchL2DataMap := make(map[uint64][]byte, len(batchNumbers))
|
| 428 |
+
for results.Next() {
|
| 429 |
+
var (
|
| 430 |
+
batchNum uint64
|
| 431 |
+
batchL2Data []byte
|
| 432 |
+
)
|
| 433 |
+
|
| 434 |
+
if err := results.Scan(&batchNum, &batchL2Data); err != nil {
|
| 435 |
+
return nil, err
|
| 436 |
+
}
|
| 437 |
+
batchL2DataMap[batchNum] = batchL2Data
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
return batchL2DataMap, nil
|
| 441 |
+
}
|
|
@@ -110,11 +110,7 @@
|
|
| 110 |
if err != nil {
|
| 111 |
panic(err)
|
| 112 |
}
|
| 113 |
-
|
| 114 |
-
if err != nil {
|
| 115 |
-
panic(err)
|
| 116 |
-
}
|
| 117 |
-
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), executorClient, stateTree, eventLog, mt, mtr)
|
| 118 |
|
| 119 |
result := m.Run()
|
| 120 |
|
|
@@ -463,7 +459,7 @@
|
|
| 463 |
batchNumber := uint64(42)
|
| 464 |
_, err = testState.Exec(ctx, "INSERT INTO state.batch (batch_num,wip) VALUES ($1, FALSE), ($2, FALSE), ($3, FALSE)", batchNumber, batchNumber+1, batchNumber+2)
|
| 465 |
require.NoError(err)
|
| 466 |
-
const addGeneratedProofSQL = "INSERT INTO state.
|
| 467 |
// proof with `generating_since` older than interval
|
| 468 |
now := time.Now().Round(time.Microsecond)
|
| 469 |
oneHourAgo := now.Add(-time.Hour).Round(time.Microsecond)
|
|
@@ -500,10 +496,10 @@
|
|
| 500 |
_, err = testState.Exec(ctx, addGeneratedProofSQL, olderNotGenProof.BatchNumber, olderNotGenProof.BatchNumberFinal, olderNotGenProof.Proof, olderNotGenProof.ProofID, olderNotGenProof.InputProver, olderNotGenProof.Prover, olderNotGenProof.ProverID, olderNotGenProof.GeneratingSince, oneHourAgo, oneHourAgo)
|
| 501 |
require.NoError(err)
|
| 502 |
|
| 503 |
-
_, err = testState.
|
| 504 |
|
| 505 |
require.NoError(err)
|
| 506 |
-
rows, err := testState.Query(ctx, "SELECT batch_num, batch_num_final, proof, proof_id, input_prover, prover, prover_id, generating_since, created_at, updated_at FROM state.
|
| 507 |
require.NoError(err)
|
| 508 |
proofs := make([]state.Proof, 0, len(rows.RawValues()))
|
| 509 |
for rows.Next() {
|
|
@@ -885,11 +881,7 @@
|
|
| 885 |
if err != nil {
|
| 886 |
panic(err)
|
| 887 |
}
|
| 888 |
-
|
| 889 |
-
if err != nil {
|
| 890 |
-
panic(err)
|
| 891 |
-
}
|
| 892 |
-
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(cfg, stateDb), executorClient, stateTree, nil, mt, mtr)
|
| 893 |
|
| 894 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 895 |
require.NoError(t, err)
|
|
@@ -1086,11 +1078,7 @@
|
|
| 1086 |
if err != nil {
|
| 1087 |
panic(err)
|
| 1088 |
}
|
| 1089 |
-
|
| 1090 |
-
if err != nil {
|
| 1091 |
-
panic(err)
|
| 1092 |
-
}
|
| 1093 |
-
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(cfg, stateDb), executorClient, stateTree, nil, mt, mtr)
|
| 1094 |
|
| 1095 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 1096 |
require.NoError(t, err)
|
|
@@ -1268,11 +1256,7 @@
|
|
| 1268 |
if err != nil {
|
| 1269 |
panic(err)
|
| 1270 |
}
|
| 1271 |
-
|
| 1272 |
-
if err != nil {
|
| 1273 |
-
panic(err)
|
| 1274 |
-
}
|
| 1275 |
-
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(cfg, stateDb), executorClient, stateTree, nil, mt, mtr)
|
| 1276 |
|
| 1277 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 1278 |
require.NoError(t, err)
|
|
@@ -1387,6 +1371,108 @@
|
|
| 1387 |
require.NoError(t, dbTx.Commit(ctx))
|
| 1388 |
}
|
| 1389 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1390 |
func createL1InfoTreeExitRootStorageEntryForTest(blockNumber uint64, index uint32) *state.L1InfoTreeExitRootStorageEntry {
|
| 1391 |
exitRoot := state.L1InfoTreeExitRootStorageEntry{
|
| 1392 |
L1InfoTreeLeaf: state.L1InfoTreeLeaf{
|
|
@@ -1588,6 +1674,13 @@
|
|
| 1588 |
require.Equal(t, uint64(2002), fb.BlockNumber)
|
| 1589 |
require.Equal(t, "0x717e05de47a87a7d1679e183f1c224150675f6302b7da4eaab526b2b91ae0761", fb.GlobalExitRoot.String())
|
| 1590 |
require.Equal(t, []byte{0xb}, fb.RawTxsData)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1591 |
}
|
| 1592 |
|
| 1593 |
func TestGetLastGER(t *testing.T) {
|
|
@@ -1664,49 +1757,6 @@
|
|
| 1664 |
ger, err = testState.GetLatestBatchGlobalExitRoot(ctx, dbTx)
|
| 1665 |
require.NoError(t, err)
|
| 1666 |
require.Equal(t, common.HexToHash("0x2").String(), ger.String())
|
| 1667 |
-
|
| 1668 |
-
}
|
| 1669 |
-
|
| 1670 |
-
func TestAddBlobSequence(t *testing.T) {
|
| 1671 |
-
initOrResetDB()
|
| 1672 |
-
ctx := context.Background()
|
| 1673 |
-
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 1674 |
-
require.NoError(t, err)
|
| 1675 |
-
defer func() { require.NoError(t, dbTx.Commit(ctx)) }()
|
| 1676 |
-
|
| 1677 |
-
block := state.NewBlock(100)
|
| 1678 |
-
err = testState.AddBlock(ctx, block, dbTx)
|
| 1679 |
-
require.NoError(t, err)
|
| 1680 |
-
|
| 1681 |
-
blobSeq := state.BlobSequence{
|
| 1682 |
-
BlobSequenceIndex: 1,
|
| 1683 |
-
BlockNumber: 100,
|
| 1684 |
-
}
|
| 1685 |
-
err = testState.AddBlobSequence(ctx, &blobSeq, dbTx)
|
| 1686 |
-
require.NoError(t, err)
|
| 1687 |
-
}
|
| 1688 |
-
|
| 1689 |
-
func TestStoreBlobInner(t *testing.T) {
|
| 1690 |
-
initOrResetDB()
|
| 1691 |
-
ctx := context.Background()
|
| 1692 |
-
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 1693 |
-
require.NoError(t, err)
|
| 1694 |
-
defer func() { require.NoError(t, dbTx.Commit(ctx)) }()
|
| 1695 |
-
block := state.NewBlock(100)
|
| 1696 |
-
err = testState.AddBlock(ctx, block, dbTx)
|
| 1697 |
-
require.NoError(t, err)
|
| 1698 |
-
|
| 1699 |
-
blobSeq := state.BlobSequence{
|
| 1700 |
-
BlobSequenceIndex: 1,
|
| 1701 |
-
BlockNumber: 100,
|
| 1702 |
-
}
|
| 1703 |
-
err = testState.AddBlobSequence(ctx, &blobSeq, dbTx)
|
| 1704 |
-
require.NoError(t, err)
|
| 1705 |
-
blobInner := state.BlobInner{
|
| 1706 |
-
BlobSequenceIndex: 1,
|
| 1707 |
-
}
|
| 1708 |
-
err = testState.AddBlobInner(ctx, &blobInner, dbTx)
|
| 1709 |
-
require.NoError(t, err)
|
| 1710 |
}
|
| 1711 |
|
| 1712 |
func TestGetFirstUncheckedBlock(t *testing.T) {
|
|
|
|
| 110 |
if err != nil {
|
| 111 |
panic(err)
|
| 112 |
}
|
| 113 |
+
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), executorClient, stateTree, eventLog, mt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
result := m.Run()
|
| 116 |
|
|
|
|
| 459 |
batchNumber := uint64(42)
|
| 460 |
_, err = testState.Exec(ctx, "INSERT INTO state.batch (batch_num,wip) VALUES ($1, FALSE), ($2, FALSE), ($3, FALSE)", batchNumber, batchNumber+1, batchNumber+2)
|
| 461 |
require.NoError(err)
|
| 462 |
+
const addGeneratedProofSQL = "INSERT INTO state.proof (batch_num, batch_num_final, proof, proof_id, input_prover, prover, prover_id, generating_since, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)"
|
| 463 |
// proof with `generating_since` older than interval
|
| 464 |
now := time.Now().Round(time.Microsecond)
|
| 465 |
oneHourAgo := now.Add(-time.Hour).Round(time.Microsecond)
|
|
|
|
| 496 |
_, err = testState.Exec(ctx, addGeneratedProofSQL, olderNotGenProof.BatchNumber, olderNotGenProof.BatchNumberFinal, olderNotGenProof.Proof, olderNotGenProof.ProofID, olderNotGenProof.InputProver, olderNotGenProof.Prover, olderNotGenProof.ProverID, olderNotGenProof.GeneratingSince, oneHourAgo, oneHourAgo)
|
| 497 |
require.NoError(err)
|
| 498 |
|
| 499 |
+
_, err = testState.CleanupLockedProofs(ctx, "1m", nil)
|
| 500 |
|
| 501 |
require.NoError(err)
|
| 502 |
+
rows, err := testState.Query(ctx, "SELECT batch_num, batch_num_final, proof, proof_id, input_prover, prover, prover_id, generating_since, created_at, updated_at FROM state.proof")
|
| 503 |
require.NoError(err)
|
| 504 |
proofs := make([]state.Proof, 0, len(rows.RawValues()))
|
| 505 |
for rows.Next() {
|
|
|
|
| 881 |
if err != nil {
|
| 882 |
panic(err)
|
| 883 |
}
|
| 884 |
+
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(cfg, stateDb), executorClient, stateTree, nil, mt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 885 |
|
| 886 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 887 |
require.NoError(t, err)
|
|
|
|
| 1078 |
if err != nil {
|
| 1079 |
panic(err)
|
| 1080 |
}
|
| 1081 |
+
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(cfg, stateDb), executorClient, stateTree, nil, mt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1082 |
|
| 1083 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 1084 |
require.NoError(t, err)
|
|
|
|
| 1256 |
if err != nil {
|
| 1257 |
panic(err)
|
| 1258 |
}
|
| 1259 |
+
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(cfg, stateDb), executorClient, stateTree, nil, mt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1260 |
|
| 1261 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 1262 |
require.NoError(t, err)
|
|
|
|
| 1371 |
require.NoError(t, dbTx.Commit(ctx))
|
| 1372 |
}
|
| 1373 |
|
| 1374 |
+
func TestGetBatchL2DataByNumber(t *testing.T) {
|
| 1375 |
+
// Init database instance
|
| 1376 |
+
initOrResetDB()
|
| 1377 |
+
ctx := context.Background()
|
| 1378 |
+
tx, err := testState.BeginStateTransaction(ctx)
|
| 1379 |
+
require.NoError(t, err)
|
| 1380 |
+
defer func() { require.NoError(t, tx.Commit(ctx)) }()
|
| 1381 |
+
|
| 1382 |
+
// empty case
|
| 1383 |
+
var batchNum uint64 = 4
|
| 1384 |
+
const (
|
| 1385 |
+
openBatchSQL = "INSERT INTO state.batch (batch_num, raw_txs_data, wip) VALUES ($1, $2, false)"
|
| 1386 |
+
resetBatchesSQL = "DELETE FROM state.batch"
|
| 1387 |
+
)
|
| 1388 |
+
_, err = tx.Exec(ctx, openBatchSQL, batchNum, nil)
|
| 1389 |
+
require.NoError(t, err)
|
| 1390 |
+
data, err := testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1391 |
+
require.NoError(t, err)
|
| 1392 |
+
assert.Nil(t, data)
|
| 1393 |
+
|
| 1394 |
+
// not empty case
|
| 1395 |
+
expectedData := []byte("foo bar")
|
| 1396 |
+
batchNum = 5
|
| 1397 |
+
_, err = tx.Exec(ctx, openBatchSQL, batchNum, expectedData)
|
| 1398 |
+
require.NoError(t, err)
|
| 1399 |
+
actualData, err := testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1400 |
+
require.NoError(t, err)
|
| 1401 |
+
assert.Equal(t, expectedData, actualData)
|
| 1402 |
+
|
| 1403 |
+
multiGet := []uint64{uint64(4), uint64(5), uint64(6)}
|
| 1404 |
+
allData, err := testState.GetBatchL2DataByNumbers(ctx, multiGet, tx)
|
| 1405 |
+
require.NoError(t, err)
|
| 1406 |
+
require.Equal(t, expectedData, allData[uint64(5)])
|
| 1407 |
+
|
| 1408 |
+
// Force backup
|
| 1409 |
+
_, err = tx.Exec(ctx, resetBatchesSQL)
|
| 1410 |
+
require.NoError(t, err)
|
| 1411 |
+
|
| 1412 |
+
// Get batch 4 from backup
|
| 1413 |
+
batchNum = 4
|
| 1414 |
+
data, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1415 |
+
require.NoError(t, err)
|
| 1416 |
+
assert.Nil(t, data)
|
| 1417 |
+
|
| 1418 |
+
// Get batch 5 from backup
|
| 1419 |
+
batchNum = 5
|
| 1420 |
+
actualData, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1421 |
+
require.NoError(t, err)
|
| 1422 |
+
assert.Equal(t, expectedData, actualData)
|
| 1423 |
+
|
| 1424 |
+
// Update batch 5 and get it from backup
|
| 1425 |
+
expectedData = []byte("new foo bar")
|
| 1426 |
+
_, err = tx.Exec(ctx, openBatchSQL, batchNum, expectedData)
|
| 1427 |
+
require.NoError(t, err)
|
| 1428 |
+
_, err = tx.Exec(ctx, resetBatchesSQL)
|
| 1429 |
+
require.NoError(t, err)
|
| 1430 |
+
actualData, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1431 |
+
require.NoError(t, err)
|
| 1432 |
+
assert.Equal(t, expectedData, actualData)
|
| 1433 |
+
}
|
| 1434 |
+
|
| 1435 |
+
func TestGetBatchL2DataByNumbers(t *testing.T) {
|
| 1436 |
+
initOrResetDB()
|
| 1437 |
+
ctx := context.Background()
|
| 1438 |
+
tx, err := testState.BeginStateTransaction(ctx)
|
| 1439 |
+
require.NoError(t, err)
|
| 1440 |
+
defer func() { require.NoError(t, tx.Commit(ctx)) }()
|
| 1441 |
+
|
| 1442 |
+
var i1, i2, i3, i4, i5 = uint64(1), uint64(2), uint64(3), uint64(4), uint64(5)
|
| 1443 |
+
var d1, d2, d4 = []byte("foobar"), []byte("dingbat"), []byte{0xb}
|
| 1444 |
+
|
| 1445 |
+
const insertBatch = "INSERT INTO state.batch (batch_num, raw_txs_data) VALUES ($1, $2)"
|
| 1446 |
+
_, err = tx.Exec(ctx, insertBatch, i1, d1)
|
| 1447 |
+
require.NoError(t, err)
|
| 1448 |
+
_, err = tx.Exec(ctx, insertBatch, i2, d2)
|
| 1449 |
+
require.NoError(t, err)
|
| 1450 |
+
_, err = tx.Exec(ctx, insertBatch, i3, nil)
|
| 1451 |
+
require.NoError(t, err)
|
| 1452 |
+
|
| 1453 |
+
// Add a forced batch too, needs a block
|
| 1454 |
+
block1 := *block
|
| 1455 |
+
block1.BlockNumber = 1000
|
| 1456 |
+
err = testState.AddBlock(ctx, &block1, tx)
|
| 1457 |
+
require.NoError(t, err)
|
| 1458 |
+
err = tx.Commit(ctx)
|
| 1459 |
+
require.NoError(t, err)
|
| 1460 |
+
|
| 1461 |
+
tx, err = testState.BeginStateTransaction(ctx)
|
| 1462 |
+
require.NoError(t, err)
|
| 1463 |
+
|
| 1464 |
+
const insertForcedBatch = "INSERT INTO state.forced_batch (forced_batch_num, timestamp, raw_txs_data, block_num) VALUES (4, now(),'0b', 1000)"
|
| 1465 |
+
_, err = testState.Exec(ctx, insertForcedBatch)
|
| 1466 |
+
require.NoError(t, err)
|
| 1467 |
+
|
| 1468 |
+
allData, err := testState.GetForcedBatchDataByNumbers(ctx, []uint64{i4}, tx)
|
| 1469 |
+
require.NoError(t, err)
|
| 1470 |
+
assert.Equal(t, d4, allData[i4])
|
| 1471 |
+
|
| 1472 |
+
_, ok := allData[i5]
|
| 1473 |
+
assert.False(t, ok)
|
| 1474 |
+
}
|
| 1475 |
+
|
| 1476 |
func createL1InfoTreeExitRootStorageEntryForTest(blockNumber uint64, index uint32) *state.L1InfoTreeExitRootStorageEntry {
|
| 1477 |
exitRoot := state.L1InfoTreeExitRootStorageEntry{
|
| 1478 |
L1InfoTreeLeaf: state.L1InfoTreeLeaf{
|
|
|
|
| 1674 |
require.Equal(t, uint64(2002), fb.BlockNumber)
|
| 1675 |
require.Equal(t, "0x717e05de47a87a7d1679e183f1c224150675f6302b7da4eaab526b2b91ae0761", fb.GlobalExitRoot.String())
|
| 1676 |
require.Equal(t, []byte{0xb}, fb.RawTxsData)
|
| 1677 |
+
|
| 1678 |
+
// also check data retrieval
|
| 1679 |
+
fbData, err := testState.GetForcedBatchDataByNumbers(ctx, []uint64{1}, dbTx)
|
| 1680 |
+
require.NoError(t, err)
|
| 1681 |
+
var expected = make(map[uint64][]byte)
|
| 1682 |
+
expected[uint64(1)] = []byte{0xb}
|
| 1683 |
+
require.Equal(t, expected, fbData)
|
| 1684 |
}
|
| 1685 |
|
| 1686 |
func TestGetLastGER(t *testing.T) {
|
|
|
|
| 1757 |
ger, err = testState.GetLatestBatchGlobalExitRoot(ctx, dbTx)
|
| 1758 |
require.NoError(t, err)
|
| 1759 |
require.Equal(t, common.HexToHash("0x2").String(), ger.String())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1760 |
}
|
| 1761 |
|
| 1762 |
func TestGetFirstUncheckedBlock(t *testing.T) {
|
|
@@ -25,9 +25,9 @@
|
|
| 25 |
return exists, nil
|
| 26 |
}
|
| 27 |
|
| 28 |
-
//
|
| 29 |
-
func (p *PostgresStorage)
|
| 30 |
-
const
|
| 31 |
SELECT
|
| 32 |
p.batch_num,
|
| 33 |
p.batch_num_final,
|
|
@@ -39,7 +39,7 @@
|
|
| 39 |
p.generating_since,
|
| 40 |
p.created_at,
|
| 41 |
p.updated_at
|
| 42 |
-
FROM state.
|
| 43 |
WHERE batch_num = $1 AND generating_since IS NULL AND
|
| 44 |
EXISTS (SELECT 1 FROM state.sequences s1 WHERE s1.from_batch_num = p.batch_num) AND
|
| 45 |
EXISTS (SELECT 1 FROM state.sequences s2 WHERE s2.to_batch_num = p.batch_num_final)
|
|
@@ -48,7 +48,7 @@
|
|
| 48 |
var proof *state.Proof = &state.Proof{}
|
| 49 |
|
| 50 |
e := p.getExecQuerier(dbTx)
|
| 51 |
-
row := e.QueryRow(ctx,
|
| 52 |
err := row.Scan(&proof.BatchNumber, &proof.BatchNumberFinal, &proof.Proof, &proof.ProofID, &proof.InputProver, &proof.Prover, &proof.ProverID, &proof.GeneratingSince, &proof.CreatedAt, &proof.UpdatedAt)
|
| 53 |
|
| 54 |
if errors.Is(err, pgx.ErrNoRows) {
|
|
@@ -60,15 +60,15 @@
|
|
| 60 |
return proof, err
|
| 61 |
}
|
| 62 |
|
| 63 |
-
//
|
| 64 |
-
func (p *PostgresStorage)
|
| 65 |
var (
|
| 66 |
proof1 *state.Proof = &state.Proof{}
|
| 67 |
proof2 *state.Proof = &state.Proof{}
|
| 68 |
)
|
| 69 |
|
| 70 |
// TODO: add comments to explain the query
|
| 71 |
-
const
|
| 72 |
SELECT
|
| 73 |
p1.batch_num as p1_batch_num,
|
| 74 |
p1.batch_num_final as p1_batch_num_final,
|
|
@@ -90,16 +90,31 @@
|
|
| 90 |
p2.generating_since as p2_generating_since,
|
| 91 |
p2.created_at as p2_created_at,
|
| 92 |
p2.updated_at as p2_updated_at
|
| 93 |
-
FROM state.
|
| 94 |
-
WHERE p1.
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
ORDER BY p1.batch_num ASC
|
| 98 |
LIMIT 1
|
| 99 |
`
|
| 100 |
|
| 101 |
e := p.getExecQuerier(dbTx)
|
| 102 |
-
row := e.QueryRow(ctx,
|
| 103 |
err := row.Scan(
|
| 104 |
&proof1.BatchNumber, &proof1.BatchNumberFinal, &proof1.Proof, &proof1.ProofID, &proof1.InputProver, &proof1.Prover, &proof1.ProverID, &proof1.GeneratingSince, &proof1.CreatedAt, &proof1.UpdatedAt,
|
| 105 |
&proof2.BatchNumber, &proof2.BatchNumberFinal, &proof2.Proof, &proof2.ProofID, &proof2.InputProver, &proof2.Prover, &proof2.ProverID, &proof2.GeneratingSince, &proof2.CreatedAt, &proof2.UpdatedAt)
|
|
@@ -113,47 +128,50 @@
|
|
| 113 |
return proof1, proof2, err
|
| 114 |
}
|
| 115 |
|
| 116 |
-
//
|
| 117 |
-
func (p *PostgresStorage)
|
| 118 |
-
const
|
| 119 |
e := p.getExecQuerier(dbTx)
|
| 120 |
now := time.Now().UTC().Round(time.Microsecond)
|
| 121 |
-
_, err := e.Exec(ctx,
|
| 122 |
return err
|
| 123 |
}
|
| 124 |
|
| 125 |
-
//
|
| 126 |
-
func (p *PostgresStorage)
|
| 127 |
-
const
|
| 128 |
e := p.getExecQuerier(dbTx)
|
| 129 |
now := time.Now().UTC().Round(time.Microsecond)
|
| 130 |
-
_, err := e.Exec(ctx,
|
| 131 |
return err
|
| 132 |
}
|
| 133 |
|
| 134 |
-
//
|
| 135 |
-
|
| 136 |
-
|
|
|
|
| 137 |
e := p.getExecQuerier(dbTx)
|
| 138 |
-
_, err := e.Exec(ctx,
|
| 139 |
return err
|
| 140 |
}
|
| 141 |
|
| 142 |
-
//
|
| 143 |
-
|
| 144 |
-
|
|
|
|
| 145 |
e := p.getExecQuerier(dbTx)
|
| 146 |
-
_, err := e.Exec(ctx,
|
| 147 |
return err
|
| 148 |
}
|
| 149 |
|
| 150 |
-
//
|
| 151 |
-
|
|
|
|
| 152 |
interval, err := toPostgresInterval(duration)
|
| 153 |
if err != nil {
|
| 154 |
return 0, err
|
| 155 |
}
|
| 156 |
-
sql := fmt.Sprintf("DELETE FROM state.
|
| 157 |
e := p.getExecQuerier(dbTx)
|
| 158 |
ct, err := e.Exec(ctx, sql)
|
| 159 |
if err != nil {
|
|
@@ -162,9 +180,10 @@
|
|
| 162 |
return ct.RowsAffected(), nil
|
| 163 |
}
|
| 164 |
|
| 165 |
-
//
|
| 166 |
-
|
| 167 |
-
|
|
|
|
| 168 |
e := p.getExecQuerier(dbTx)
|
| 169 |
_, err := e.Exec(ctx, deleteUngeneratedProofsSQL)
|
| 170 |
return err
|
|
|
|
| 25 |
return exists, nil
|
| 26 |
}
|
| 27 |
|
| 28 |
+
// GetProofReadyToVerify return the proof that is ready to verify
|
| 29 |
+
func (p *PostgresStorage) GetProofReadyToVerify(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Proof, error) {
|
| 30 |
+
const getProofReadyToVerifySQL = `
|
| 31 |
SELECT
|
| 32 |
p.batch_num,
|
| 33 |
p.batch_num_final,
|
|
|
|
| 39 |
p.generating_since,
|
| 40 |
p.created_at,
|
| 41 |
p.updated_at
|
| 42 |
+
FROM state.proof p
|
| 43 |
WHERE batch_num = $1 AND generating_since IS NULL AND
|
| 44 |
EXISTS (SELECT 1 FROM state.sequences s1 WHERE s1.from_batch_num = p.batch_num) AND
|
| 45 |
EXISTS (SELECT 1 FROM state.sequences s2 WHERE s2.to_batch_num = p.batch_num_final)
|
|
|
|
| 48 |
var proof *state.Proof = &state.Proof{}
|
| 49 |
|
| 50 |
e := p.getExecQuerier(dbTx)
|
| 51 |
+
row := e.QueryRow(ctx, getProofReadyToVerifySQL, lastVerfiedBatchNumber+1)
|
| 52 |
err := row.Scan(&proof.BatchNumber, &proof.BatchNumberFinal, &proof.Proof, &proof.ProofID, &proof.InputProver, &proof.Prover, &proof.ProverID, &proof.GeneratingSince, &proof.CreatedAt, &proof.UpdatedAt)
|
| 53 |
|
| 54 |
if errors.Is(err, pgx.ErrNoRows) {
|
|
|
|
| 60 |
return proof, err
|
| 61 |
}
|
| 62 |
|
| 63 |
+
// GetProofsToAggregate return the next to proof that it is possible to aggregate
|
| 64 |
+
func (p *PostgresStorage) GetProofsToAggregate(ctx context.Context, dbTx pgx.Tx) (*state.Proof, *state.Proof, error) {
|
| 65 |
var (
|
| 66 |
proof1 *state.Proof = &state.Proof{}
|
| 67 |
proof2 *state.Proof = &state.Proof{}
|
| 68 |
)
|
| 69 |
|
| 70 |
// TODO: add comments to explain the query
|
| 71 |
+
const getProofsToAggregateSQL = `
|
| 72 |
SELECT
|
| 73 |
p1.batch_num as p1_batch_num,
|
| 74 |
p1.batch_num_final as p1_batch_num_final,
|
|
|
|
| 90 |
p2.generating_since as p2_generating_since,
|
| 91 |
p2.created_at as p2_created_at,
|
| 92 |
p2.updated_at as p2_updated_at
|
| 93 |
+
FROM state.proof p1 INNER JOIN state.proof p2 ON p1.batch_num_final = p2.batch_num - 1
|
| 94 |
+
WHERE p1.generating_since IS NULL AND p2.generating_since IS NULL AND
|
| 95 |
+
p1.proof IS NOT NULL AND p2.proof IS NOT NULL AND
|
| 96 |
+
(
|
| 97 |
+
EXISTS (
|
| 98 |
+
SELECT 1 FROM state.sequences s
|
| 99 |
+
WHERE p1.batch_num >= s.from_batch_num AND p1.batch_num <= s.to_batch_num AND
|
| 100 |
+
p1.batch_num_final >= s.from_batch_num AND p1.batch_num_final <= s.to_batch_num AND
|
| 101 |
+
p2.batch_num >= s.from_batch_num AND p2.batch_num <= s.to_batch_num AND
|
| 102 |
+
p2.batch_num_final >= s.from_batch_num AND p2.batch_num_final <= s.to_batch_num
|
| 103 |
+
)
|
| 104 |
+
OR
|
| 105 |
+
(
|
| 106 |
+
EXISTS ( SELECT 1 FROM state.sequences s WHERE p1.batch_num = s.from_batch_num) AND
|
| 107 |
+
EXISTS ( SELECT 1 FROM state.sequences s WHERE p1.batch_num_final = s.to_batch_num) AND
|
| 108 |
+
EXISTS ( SELECT 1 FROM state.sequences s WHERE p2.batch_num = s.from_batch_num) AND
|
| 109 |
+
EXISTS ( SELECT 1 FROM state.sequences s WHERE p2.batch_num_final = s.to_batch_num)
|
| 110 |
+
)
|
| 111 |
+
)
|
| 112 |
ORDER BY p1.batch_num ASC
|
| 113 |
LIMIT 1
|
| 114 |
`
|
| 115 |
|
| 116 |
e := p.getExecQuerier(dbTx)
|
| 117 |
+
row := e.QueryRow(ctx, getProofsToAggregateSQL)
|
| 118 |
err := row.Scan(
|
| 119 |
&proof1.BatchNumber, &proof1.BatchNumberFinal, &proof1.Proof, &proof1.ProofID, &proof1.InputProver, &proof1.Prover, &proof1.ProverID, &proof1.GeneratingSince, &proof1.CreatedAt, &proof1.UpdatedAt,
|
| 120 |
&proof2.BatchNumber, &proof2.BatchNumberFinal, &proof2.Proof, &proof2.ProofID, &proof2.InputProver, &proof2.Prover, &proof2.ProverID, &proof2.GeneratingSince, &proof2.CreatedAt, &proof2.UpdatedAt)
|
|
|
|
| 128 |
return proof1, proof2, err
|
| 129 |
}
|
| 130 |
|
| 131 |
+
// AddGeneratedProof adds a generated proof to the storage
|
| 132 |
+
func (p *PostgresStorage) AddGeneratedProof(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) error {
|
| 133 |
+
const addGeneratedProofSQL = "INSERT INTO state.proof (batch_num, batch_num_final, proof, proof_id, input_prover, prover, prover_id, generating_since, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)"
|
| 134 |
e := p.getExecQuerier(dbTx)
|
| 135 |
now := time.Now().UTC().Round(time.Microsecond)
|
| 136 |
+
_, err := e.Exec(ctx, addGeneratedProofSQL, proof.BatchNumber, proof.BatchNumberFinal, proof.Proof, proof.ProofID, proof.InputProver, proof.Prover, proof.ProverID, proof.GeneratingSince, now, now)
|
| 137 |
return err
|
| 138 |
}
|
| 139 |
|
| 140 |
+
// UpdateGeneratedProof updates a generated proof in the storage
|
| 141 |
+
func (p *PostgresStorage) UpdateGeneratedProof(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) error {
|
| 142 |
+
const addGeneratedProofSQL = "UPDATE state.proof SET proof = $3, proof_id = $4, input_prover = $5, prover = $6, prover_id = $7, generating_since = $8, updated_at = $9 WHERE batch_num = $1 AND batch_num_final = $2"
|
| 143 |
e := p.getExecQuerier(dbTx)
|
| 144 |
now := time.Now().UTC().Round(time.Microsecond)
|
| 145 |
+
_, err := e.Exec(ctx, addGeneratedProofSQL, proof.BatchNumber, proof.BatchNumberFinal, proof.Proof, proof.ProofID, proof.InputProver, proof.Prover, proof.ProverID, proof.GeneratingSince, now)
|
| 146 |
return err
|
| 147 |
}
|
| 148 |
|
| 149 |
+
// DeleteGeneratedProofs deletes from the storage the generated proofs falling
|
| 150 |
+
// inside the batch numbers range.
|
| 151 |
+
func (p *PostgresStorage) DeleteGeneratedProofs(ctx context.Context, batchNumber uint64, batchNumberFinal uint64, dbTx pgx.Tx) error {
|
| 152 |
+
const deleteGeneratedProofSQL = "DELETE FROM state.proof WHERE batch_num >= $1 AND batch_num_final <= $2"
|
| 153 |
e := p.getExecQuerier(dbTx)
|
| 154 |
+
_, err := e.Exec(ctx, deleteGeneratedProofSQL, batchNumber, batchNumberFinal)
|
| 155 |
return err
|
| 156 |
}
|
| 157 |
|
| 158 |
+
// CleanupGeneratedProofs deletes from the storage the generated proofs up to
|
| 159 |
+
// the specified batch number included.
|
| 160 |
+
func (p *PostgresStorage) CleanupGeneratedProofs(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error {
|
| 161 |
+
const deleteGeneratedProofSQL = "DELETE FROM state.proof WHERE batch_num_final <= $1"
|
| 162 |
e := p.getExecQuerier(dbTx)
|
| 163 |
+
_, err := e.Exec(ctx, deleteGeneratedProofSQL, batchNumber)
|
| 164 |
return err
|
| 165 |
}
|
| 166 |
|
| 167 |
+
// CleanupLockedProofs deletes from the storage the proofs locked in generating
|
| 168 |
+
// state for more than the provided threshold.
|
| 169 |
+
func (p *PostgresStorage) CleanupLockedProofs(ctx context.Context, duration string, dbTx pgx.Tx) (int64, error) {
|
| 170 |
interval, err := toPostgresInterval(duration)
|
| 171 |
if err != nil {
|
| 172 |
return 0, err
|
| 173 |
}
|
| 174 |
+
sql := fmt.Sprintf("DELETE FROM state.proof WHERE generating_since < (NOW() - interval '%s')", interval)
|
| 175 |
e := p.getExecQuerier(dbTx)
|
| 176 |
ct, err := e.Exec(ctx, sql)
|
| 177 |
if err != nil {
|
|
|
|
| 180 |
return ct.RowsAffected(), nil
|
| 181 |
}
|
| 182 |
|
| 183 |
+
// DeleteUngeneratedProofs deletes ungenerated proofs.
|
| 184 |
+
// This method is meant to be use during aggregator boot-up sequence
|
| 185 |
+
func (p *PostgresStorage) DeleteUngeneratedProofs(ctx context.Context, dbTx pgx.Tx) error {
|
| 186 |
+
const deleteUngeneratedProofsSQL = "DELETE FROM state.proof WHERE generating_since IS NOT NULL"
|
| 187 |
e := p.getExecQuerier(dbTx)
|
| 188 |
_, err := e.Exec(ctx, deleteUngeneratedProofsSQL)
|
| 189 |
return err
|
|
@@ -63,16 +63,13 @@
|
|
| 63 |
} else if err != nil {
|
| 64 |
return nil, err
|
| 65 |
}
|
| 66 |
-
|
| 67 |
-
defer rows.Close()
|
| 68 |
-
|
| 69 |
hashes := make([]common.Hash, 0, len(rows.RawValues()))
|
| 70 |
for rows.Next() {
|
| 71 |
var hash string
|
| 72 |
-
|
|
|
|
| 73 |
return nil, err
|
| 74 |
}
|
| 75 |
-
|
| 76 |
hashes = append(hashes, common.HexToHash(hash))
|
| 77 |
}
|
| 78 |
|
|
@@ -111,16 +108,13 @@
|
|
| 111 |
} else if err != nil {
|
| 112 |
return nil, err
|
| 113 |
}
|
| 114 |
-
|
| 115 |
-
defer rows.Close()
|
| 116 |
-
|
| 117 |
hashes := make([]common.Hash, 0, len(rows.RawValues()))
|
| 118 |
for rows.Next() {
|
| 119 |
var hash string
|
| 120 |
-
|
|
|
|
| 121 |
return nil, err
|
| 122 |
}
|
| 123 |
-
|
| 124 |
hashes = append(hashes, common.HexToHash(hash))
|
| 125 |
}
|
| 126 |
|
|
|
|
| 63 |
} else if err != nil {
|
| 64 |
return nil, err
|
| 65 |
}
|
|
|
|
|
|
|
|
|
|
| 66 |
hashes := make([]common.Hash, 0, len(rows.RawValues()))
|
| 67 |
for rows.Next() {
|
| 68 |
var hash string
|
| 69 |
+
err := rows.Scan(&hash)
|
| 70 |
+
if err != nil {
|
| 71 |
return nil, err
|
| 72 |
}
|
|
|
|
| 73 |
hashes = append(hashes, common.HexToHash(hash))
|
| 74 |
}
|
| 75 |
|
|
|
|
| 108 |
} else if err != nil {
|
| 109 |
return nil, err
|
| 110 |
}
|
|
|
|
|
|
|
|
|
|
| 111 |
hashes := make([]common.Hash, 0, len(rows.RawValues()))
|
| 112 |
for rows.Next() {
|
| 113 |
var hash string
|
| 114 |
+
err := rows.Scan(&hash)
|
| 115 |
+
if err != nil {
|
| 116 |
return nil, err
|
| 117 |
}
|
|
|
|
| 118 |
hashes = append(hashes, common.HexToHash(hash))
|
| 119 |
}
|
| 120 |
|
|
@@ -14,7 +14,6 @@
|
|
| 14 |
// - VerifiedBatches
|
| 15 |
// - Entries in exit_root table
|
| 16 |
err := s.ResetToL1BlockNumber(ctx, blockNumber, dbTx)
|
| 17 |
-
|
| 18 |
if err != nil {
|
| 19 |
log.Error("error resetting L1BlockNumber. Error: ", err)
|
| 20 |
return err
|
|
@@ -30,5 +29,4 @@
|
|
| 30 |
// is going to be a commit or a rollback. So is going to be rebuild on the next
|
| 31 |
// request that needs it.
|
| 32 |
s.l1InfoTree = nil
|
| 33 |
-
s.l1InfoTreeRecursive = nil
|
| 34 |
}
|
|
|
|
| 14 |
// - VerifiedBatches
|
| 15 |
// - Entries in exit_root table
|
| 16 |
err := s.ResetToL1BlockNumber(ctx, blockNumber, dbTx)
|
|
|
|
| 17 |
if err != nil {
|
| 18 |
log.Error("error resetting L1BlockNumber. Error: ", err)
|
| 19 |
return err
|
|
|
|
| 29 |
// is going to be a commit or a rollback. So is going to be rebuild on the next
|
| 30 |
// request that needs it.
|
| 31 |
s.l1InfoTree = nil
|
|
|
|
| 32 |
}
|
|
@@ -7,20 +7,26 @@
|
|
| 7 |
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
"google.golang.org/grpc"
|
| 10 |
-
"google.golang.org/grpc/connectivity"
|
| 11 |
"google.golang.org/grpc/credentials/insecure"
|
| 12 |
)
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
// NewExecutorClient is the executor client constructor.
|
| 15 |
func NewExecutorClient(ctx context.Context, c Config) (ExecutorServiceClient, *grpc.ClientConn, context.CancelFunc) {
|
| 16 |
opts := []grpc.DialOption{
|
| 17 |
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
| 18 |
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(c.MaxGRPCMessageSize)),
|
|
|
|
| 19 |
}
|
| 20 |
-
const maxWaitSeconds =
|
| 21 |
const maxRetries = 5
|
| 22 |
-
|
| 23 |
-
var cancel context.CancelFunc
|
| 24 |
|
| 25 |
connectionRetries := 0
|
| 26 |
|
|
@@ -28,15 +34,8 @@
|
|
| 28 |
var err error
|
| 29 |
delay := 2
|
| 30 |
for connectionRetries < maxRetries {
|
| 31 |
-
innerCtx, cancel = context.WithTimeout(ctx, maxWaitSeconds*time.Second)
|
| 32 |
-
executorConn, err = grpc.NewClient(c.URI, opts...)
|
| 33 |
-
if err != nil {
|
| 34 |
-
log.Fatalf("fail to create grpc connection to merkletree: %v", err)
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
log.Infof("trying to connect to executor: %v", c.URI)
|
| 38 |
-
executorConn.
|
| 39 |
-
err = waitForConnection(innerCtx, executorConn)
|
| 40 |
if err != nil {
|
| 41 |
log.Infof("Retrying connection to executor #%d", connectionRetries)
|
| 42 |
time.Sleep(time.Duration(delay) * time.Second)
|
|
@@ -57,17 +56,3 @@
|
|
| 57 |
executorClient := NewExecutorServiceClient(executorConn)
|
| 58 |
return executorClient, executorConn, cancel
|
| 59 |
}
|
| 60 |
-
|
| 61 |
-
func waitForConnection(ctx context.Context, conn *grpc.ClientConn) error {
|
| 62 |
-
for {
|
| 63 |
-
select {
|
| 64 |
-
case <-ctx.Done():
|
| 65 |
-
return ctx.Err()
|
| 66 |
-
case <-time.After(time.Second):
|
| 67 |
-
s := conn.GetState()
|
| 68 |
-
if s == connectivity.Ready {
|
| 69 |
-
return nil
|
| 70 |
-
}
|
| 71 |
-
}
|
| 72 |
-
}
|
| 73 |
-
}
|
|
|
|
| 7 |
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
"google.golang.org/grpc"
|
|
|
|
| 10 |
"google.golang.org/grpc/credentials/insecure"
|
| 11 |
)
|
| 12 |
|
| 13 |
+
const (
|
| 14 |
+
// ExecutionMode0 is the execution mode for the sequencer and RPC, default one
|
| 15 |
+
ExecutionMode0 = uint64(0)
|
| 16 |
+
// ExecutionMode1 is the execution mode for the synchronizer
|
| 17 |
+
ExecutionMode1 = uint64(1)
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
// NewExecutorClient is the executor client constructor.
|
| 21 |
func NewExecutorClient(ctx context.Context, c Config) (ExecutorServiceClient, *grpc.ClientConn, context.CancelFunc) {
|
| 22 |
opts := []grpc.DialOption{
|
| 23 |
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
| 24 |
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(c.MaxGRPCMessageSize)),
|
| 25 |
+
grpc.WithBlock(),
|
| 26 |
}
|
| 27 |
+
const maxWaitSeconds = 120
|
| 28 |
const maxRetries = 5
|
| 29 |
+
ctx, cancel := context.WithTimeout(ctx, maxWaitSeconds*time.Second)
|
|
|
|
| 30 |
|
| 31 |
connectionRetries := 0
|
| 32 |
|
|
|
|
| 34 |
var err error
|
| 35 |
delay := 2
|
| 36 |
for connectionRetries < maxRetries {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
log.Infof("trying to connect to executor: %v", c.URI)
|
| 38 |
+
executorConn, err = grpc.DialContext(ctx, c.URI, opts...)
|
|
|
|
| 39 |
if err != nil {
|
| 40 |
log.Infof("Retrying connection to executor #%d", connectionRetries)
|
| 41 |
time.Sleep(time.Duration(delay) * time.Second)
|
|
|
|
| 56 |
executorClient := NewExecutorServiceClient(executorConn)
|
| 57 |
return executorClient, executorConn, cancel
|
| 58 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -20,13 +20,6 @@
|
|
| 20 |
ErrROMUnknown = fmt.Errorf("unknown ROM error")
|
| 21 |
// ErrCodeROMUnknown indicates an unknown ROM error
|
| 22 |
ErrCodeROMUnknown = RomError(math.MaxInt32)
|
| 23 |
-
|
| 24 |
-
// ErrROMBlobUnspecified indicates an unspecified ROM blob error
|
| 25 |
-
ErrROMBlobUnspecified = fmt.Errorf("unspecified ROM blob error")
|
| 26 |
-
// ErrROMBlobUnknown indicates an unknown ROM blob error
|
| 27 |
-
ErrROMBlobUnknown = fmt.Errorf("unknown ROM blob error")
|
| 28 |
-
// ErrCodeROMBlobUnknown indicates an unknown ROM blob error
|
| 29 |
-
ErrCodeROMBlobUnknown = RomBlobError(math.MaxInt32)
|
| 30 |
)
|
| 31 |
|
| 32 |
// RomErr returns an instance of error related to the ExecutorError
|
|
@@ -103,9 +96,6 @@
|
|
| 103 |
return runtime.ErrInvalidTxChangeL2BlockLimitTimestamp
|
| 104 |
case RomError_ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP:
|
| 105 |
return runtime.ErrInvalidTxChangeL2BlockMinTimestamp
|
| 106 |
-
// Start of V3 errors
|
| 107 |
-
case RomError_ROM_ERROR_INVALID_L1_INFO_TREE_INDEX:
|
| 108 |
-
return runtime.ErrInvalidL1InfoTreeIndex
|
| 109 |
}
|
| 110 |
return ErrROMUnknown
|
| 111 |
}
|
|
@@ -182,8 +172,6 @@
|
|
| 182 |
return RomError_ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_LIMIT_TIMESTAMP
|
| 183 |
case runtime.ErrInvalidTxChangeL2BlockMinTimestamp:
|
| 184 |
return RomError_ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP
|
| 185 |
-
case runtime.ErrInvalidL1InfoTreeIndex:
|
| 186 |
-
return RomError_ROM_ERROR_INVALID_L1_INFO_TREE_INDEX
|
| 187 |
}
|
| 188 |
return ErrCodeROMUnknown
|
| 189 |
}
|
|
@@ -468,49 +456,7 @@
|
|
| 468 |
return runtime.ErrExecutorErrorInvalidUpdateMerkleTree
|
| 469 |
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR:
|
| 470 |
return runtime.ErrExecutorErrorSMMainInvalidTxStatusError
|
| 471 |
-
// Start of V3 errors
|
| 472 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_PREVIOUS_L1_INFO_TREE_ROOT:
|
| 473 |
-
return runtime.ErrExecutorErrorInvalidPreviousL1InfoTreeRoot
|
| 474 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_FORCED_HASH_DATA:
|
| 475 |
-
return runtime.ErrExecutorErrorInvalidForcedHashData
|
| 476 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_FORCED_DATA_GLOBAL_EXIT_ROOT:
|
| 477 |
-
return runtime.ErrExecutorErrorInvalidForcedDataGlobalExitRoot
|
| 478 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_FORCED_DATA_BLOCK_HASH_L1:
|
| 479 |
-
return runtime.ErrExecutorErrorInvalidForcedDataBlockHashL1
|
| 480 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_L1_DATA_V3_INITIAL_HISTORIC_ROOT:
|
| 481 |
-
return runtime.ErrExecutorErrorInvalidL1DataV3InitialHistoricRoot
|
| 482 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_OLD_BLOB_STATE_ROOT:
|
| 483 |
-
return runtime.ErrExecutorErrorInvalidOldBlobStateRoot
|
| 484 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_OLD_BLOB_ACC_INPUT_HASH:
|
| 485 |
-
return runtime.ErrExecutorErrorInvalidOldBlobAccInputHash
|
| 486 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_LAST_L1_INFO_TREE_ROOT:
|
| 487 |
-
return runtime.ErrExecutorErrorInvalidLastL1InfoTreeRoot
|
| 488 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_NEW_BLOB_STATE_ROOT:
|
| 489 |
-
return runtime.ErrExecutorErrorInvalidNewBlobStateRoot
|
| 490 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_NEW_BLOB_ACC_INPUT_HASH:
|
| 491 |
-
return runtime.ErrExecutorErrorInvalidNewBlobAccInputHash
|
| 492 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_BLOB_DATA:
|
| 493 |
-
return runtime.ErrExecutorErrorInvalidBlobData
|
| 494 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_ZK_GAS_LIMIT:
|
| 495 |
-
return runtime.ErrExecutorErrorInvalidZKGasLimit
|
| 496 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_POINT_Z:
|
| 497 |
-
return runtime.ErrExecutorErrorInvalidPointZ
|
| 498 |
-
case ExecutorError_EXECUTOR_ERROR_INVALID_POINT_Y:
|
| 499 |
-
return runtime.ErrExecutorErrorInvalidPointY
|
| 500 |
-
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_POINT_Z_MISMATCH:
|
| 501 |
-
return runtime.ErrExecutorErrorSMMainPointZMismatch
|
| 502 |
-
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_BLOB_L2_HASH_DATA_MISMATCH:
|
| 503 |
-
return runtime.ErrExecutorErrorSMMainBlobL2HashDataMismatch
|
| 504 |
-
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_BATCH_HASH_DATA_MISMATCH:
|
| 505 |
-
return runtime.ErrExecutorErrorSMMainBatchHashDataMismatch
|
| 506 |
-
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_BLOB_TYPE:
|
| 507 |
-
return runtime.ErrExecutorErrorSMMainInvalidBlobType
|
| 508 |
-
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_UNRESTORED_SAVED_CONTEXT:
|
| 509 |
-
return runtime.ErrExecutorErrorSMMainUnrestoredSavedContext
|
| 510 |
-
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_MEMORY_CTX:
|
| 511 |
-
return runtime.ErrExecutorErrorSMMainInvalidMemoryCtx
|
| 512 |
}
|
| 513 |
-
|
| 514 |
return ErrExecutorUnknown
|
| 515 |
}
|
| 516 |
|
|
@@ -752,96 +698,7 @@
|
|
| 752 |
return ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE
|
| 753 |
case runtime.ErrExecutorErrorSMMainInvalidTxStatusError:
|
| 754 |
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR
|
| 755 |
-
// Start of V3 errors
|
| 756 |
-
case runtime.ErrExecutorErrorInvalidPreviousL1InfoTreeRoot:
|
| 757 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_PREVIOUS_L1_INFO_TREE_ROOT
|
| 758 |
-
case runtime.ErrExecutorErrorInvalidForcedHashData:
|
| 759 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_FORCED_HASH_DATA
|
| 760 |
-
case runtime.ErrExecutorErrorInvalidForcedDataGlobalExitRoot:
|
| 761 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_FORCED_DATA_GLOBAL_EXIT_ROOT
|
| 762 |
-
case runtime.ErrExecutorErrorInvalidForcedDataBlockHashL1:
|
| 763 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_FORCED_DATA_BLOCK_HASH_L1
|
| 764 |
-
case runtime.ErrExecutorErrorInvalidL1DataV3InitialHistoricRoot:
|
| 765 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_L1_DATA_V3_INITIAL_HISTORIC_ROOT
|
| 766 |
-
case runtime.ErrExecutorErrorInvalidOldBlobStateRoot:
|
| 767 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_OLD_BLOB_STATE_ROOT
|
| 768 |
-
case runtime.ErrExecutorErrorInvalidOldBlobAccInputHash:
|
| 769 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_OLD_BLOB_ACC_INPUT_HASH
|
| 770 |
-
case runtime.ErrExecutorErrorInvalidLastL1InfoTreeRoot:
|
| 771 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_LAST_L1_INFO_TREE_ROOT
|
| 772 |
-
case runtime.ErrExecutorErrorInvalidNewBlobStateRoot:
|
| 773 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_NEW_BLOB_STATE_ROOT
|
| 774 |
-
case runtime.ErrExecutorErrorInvalidNewBlobAccInputHash:
|
| 775 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_NEW_BLOB_ACC_INPUT_HASH
|
| 776 |
-
case runtime.ErrExecutorErrorInvalidBlobData:
|
| 777 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_BLOB_DATA
|
| 778 |
-
case runtime.ErrExecutorErrorInvalidZKGasLimit:
|
| 779 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_ZK_GAS_LIMIT
|
| 780 |
-
case runtime.ErrExecutorErrorInvalidPointZ:
|
| 781 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_POINT_Z
|
| 782 |
-
case runtime.ErrExecutorErrorInvalidPointY:
|
| 783 |
-
return ExecutorError_EXECUTOR_ERROR_INVALID_POINT_Y
|
| 784 |
-
case runtime.ErrExecutorErrorSMMainPointZMismatch:
|
| 785 |
-
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_POINT_Z_MISMATCH
|
| 786 |
-
case runtime.ErrExecutorErrorSMMainBlobL2HashDataMismatch:
|
| 787 |
-
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_BLOB_L2_HASH_DATA_MISMATCH
|
| 788 |
-
case runtime.ErrExecutorErrorSMMainBatchHashDataMismatch:
|
| 789 |
-
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_BATCH_HASH_DATA_MISMATCH
|
| 790 |
-
case runtime.ErrExecutorErrorSMMainInvalidBlobType:
|
| 791 |
-
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_BLOB_TYPE
|
| 792 |
-
case runtime.ErrExecutorErrorSMMainUnrestoredSavedContext:
|
| 793 |
-
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_UNRESTORED_SAVED_CONTEXT
|
| 794 |
-
case runtime.ErrExecutorErrorSMMainInvalidMemoryCtx:
|
| 795 |
-
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_MEMORY_CTX
|
| 796 |
}
|
| 797 |
|
| 798 |
return ErrCodeExecutorUnknown
|
| 799 |
}
|
| 800 |
-
|
| 801 |
-
// RomBlobErr returns an instance of error related to the ExecutorError
|
| 802 |
-
func RomBlobErr(errorCode RomBlobError) error {
|
| 803 |
-
switch errorCode {
|
| 804 |
-
case RomBlobError_ROM_BLOB_ERROR_UNSPECIFIED:
|
| 805 |
-
return ErrROMBlobUnspecified
|
| 806 |
-
case RomBlobError_ROM_BLOB_ERROR_NO_ERROR:
|
| 807 |
-
return nil
|
| 808 |
-
case RomBlobError_ROM_BLOB_ERROR_INVALID_PARSING:
|
| 809 |
-
return runtime.ErrROMBlobInvalidParsing
|
| 810 |
-
case RomBlobError_ROM_BLOB_ERROR_INVALID_MSB_BYTE:
|
| 811 |
-
return runtime.ErrROMBlobInvalidMSBByte
|
| 812 |
-
case RomBlobError_ROM_BLOB_ERROR_INVALID_ZK_GAS_LIMIT:
|
| 813 |
-
return runtime.ErrROMBlobInvalidZKGasLimit
|
| 814 |
-
case RomBlobError_ROM_BLOB_ERROR_INVALID_BLOB_TYPE:
|
| 815 |
-
return runtime.ErrROMBlobInvalidBlobType
|
| 816 |
-
case RomBlobError_ROM_BLOB_ERROR_INVALID_COMPRESSION_TYPE:
|
| 817 |
-
return runtime.ErrROMBlobInvalidCompressionType
|
| 818 |
-
case RomBlobError_ROM_BLOB_ERROR_INVALID_FORCED_BATCHES:
|
| 819 |
-
return runtime.ErrROMBlobInvalidForcedBatches
|
| 820 |
-
case RomBlobError_ROM_BLOB_ERROR_INVALID_TOTALBODY_LEN:
|
| 821 |
-
return runtime.ErrROMBlobInvalidTotalBodyLen
|
| 822 |
-
}
|
| 823 |
-
return ErrROMBlobUnknown
|
| 824 |
-
}
|
| 825 |
-
|
| 826 |
-
// RomBlobErrorCode returns the error code for a given error
|
| 827 |
-
func RomBlobErrorCode(err error) RomBlobError {
|
| 828 |
-
switch err {
|
| 829 |
-
case nil:
|
| 830 |
-
return RomBlobError_ROM_BLOB_ERROR_NO_ERROR
|
| 831 |
-
case runtime.ErrROMBlobInvalidParsing:
|
| 832 |
-
return RomBlobError_ROM_BLOB_ERROR_INVALID_PARSING
|
| 833 |
-
case runtime.ErrROMBlobInvalidMSBByte:
|
| 834 |
-
return RomBlobError_ROM_BLOB_ERROR_INVALID_MSB_BYTE
|
| 835 |
-
case runtime.ErrROMBlobInvalidZKGasLimit:
|
| 836 |
-
return RomBlobError_ROM_BLOB_ERROR_INVALID_ZK_GAS_LIMIT
|
| 837 |
-
case runtime.ErrROMBlobInvalidBlobType:
|
| 838 |
-
return RomBlobError_ROM_BLOB_ERROR_INVALID_BLOB_TYPE
|
| 839 |
-
case runtime.ErrROMBlobInvalidCompressionType:
|
| 840 |
-
return RomBlobError_ROM_BLOB_ERROR_INVALID_COMPRESSION_TYPE
|
| 841 |
-
case runtime.ErrROMBlobInvalidForcedBatches:
|
| 842 |
-
return RomBlobError_ROM_BLOB_ERROR_INVALID_FORCED_BATCHES
|
| 843 |
-
case runtime.ErrROMBlobInvalidTotalBodyLen:
|
| 844 |
-
return RomBlobError_ROM_BLOB_ERROR_INVALID_TOTALBODY_LEN
|
| 845 |
-
}
|
| 846 |
-
return ErrCodeROMBlobUnknown
|
| 847 |
-
}
|
|
|
|
| 20 |
ErrROMUnknown = fmt.Errorf("unknown ROM error")
|
| 21 |
// ErrCodeROMUnknown indicates an unknown ROM error
|
| 22 |
ErrCodeROMUnknown = RomError(math.MaxInt32)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
)
|
| 24 |
|
| 25 |
// RomErr returns an instance of error related to the ExecutorError
|
|
|
|
| 96 |
return runtime.ErrInvalidTxChangeL2BlockLimitTimestamp
|
| 97 |
case RomError_ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP:
|
| 98 |
return runtime.ErrInvalidTxChangeL2BlockMinTimestamp
|
|
|
|
|
|
|
|
|
|
| 99 |
}
|
| 100 |
return ErrROMUnknown
|
| 101 |
}
|
|
|
|
| 172 |
return RomError_ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_LIMIT_TIMESTAMP
|
| 173 |
case runtime.ErrInvalidTxChangeL2BlockMinTimestamp:
|
| 174 |
return RomError_ROM_ERROR_INVALID_TX_CHANGE_L2_BLOCK_MIN_TIMESTAMP
|
|
|
|
|
|
|
| 175 |
}
|
| 176 |
return ErrCodeROMUnknown
|
| 177 |
}
|
|
|
|
| 456 |
return runtime.ErrExecutorErrorInvalidUpdateMerkleTree
|
| 457 |
case ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR:
|
| 458 |
return runtime.ErrExecutorErrorSMMainInvalidTxStatusError
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
}
|
|
|
|
| 460 |
return ErrExecutorUnknown
|
| 461 |
}
|
| 462 |
|
|
|
|
| 698 |
return ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE
|
| 699 |
case runtime.ErrExecutorErrorSMMainInvalidTxStatusError:
|
| 700 |
return ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 701 |
}
|
| 702 |
|
| 703 |
return ErrCodeExecutorUnknown
|
| 704 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -16,7 +16,7 @@
|
|
| 16 |
// MarshalJSON marshals as JSON.
|
| 17 |
func (c callFrame) MarshalJSON() ([]byte, error) {
|
| 18 |
type callFrame0 struct {
|
| 19 |
-
Type fakevm.OpCode
|
| 20 |
From common.Address `json:"from"`
|
| 21 |
Gas hexutil.Uint64 `json:"gas"`
|
| 22 |
GasUsed hexutil.Uint64 `json:"gasUsed"`
|
|
@@ -50,7 +50,7 @@
|
|
| 50 |
// UnmarshalJSON unmarshals from JSON.
|
| 51 |
func (c *callFrame) UnmarshalJSON(input []byte) error {
|
| 52 |
type callFrame0 struct {
|
| 53 |
-
Type *fakevm.OpCode
|
| 54 |
From *common.Address `json:"from"`
|
| 55 |
Gas *hexutil.Uint64 `json:"gas"`
|
| 56 |
GasUsed *hexutil.Uint64 `json:"gasUsed"`
|
|
|
|
| 16 |
// MarshalJSON marshals as JSON.
|
| 17 |
func (c callFrame) MarshalJSON() ([]byte, error) {
|
| 18 |
type callFrame0 struct {
|
| 19 |
+
Type fakevm.OpCode `json:"-"`
|
| 20 |
From common.Address `json:"from"`
|
| 21 |
Gas hexutil.Uint64 `json:"gas"`
|
| 22 |
GasUsed hexutil.Uint64 `json:"gasUsed"`
|
|
|
|
| 50 |
// UnmarshalJSON unmarshals from JSON.
|
| 51 |
func (c *callFrame) UnmarshalJSON(input []byte) error {
|
| 52 |
type callFrame0 struct {
|
| 53 |
+
Type *fakevm.OpCode `json:"-"`
|
| 54 |
From *common.Address `json:"from"`
|
| 55 |
Gas *hexutil.Uint64 `json:"gas"`
|
| 56 |
GasUsed *hexutil.Uint64 `json:"gasUsed"`
|
|
@@ -83,11 +83,6 @@
|
|
| 83 |
// ErrInvalidTxChangeL2BlockMinTimestamp indicates that the change l2 block transaction has trigger an error while executing
|
| 84 |
ErrInvalidTxChangeL2BlockMinTimestamp = errors.New("indicates that the change l2 block transaction has trigger an error while executing (min timestamp)")
|
| 85 |
|
| 86 |
-
// Start of V3 errors
|
| 87 |
-
|
| 88 |
-
// ErrInvalidL1InfoTreeIndex indicates that the l1 info tree index added is not valid since its value is 0
|
| 89 |
-
ErrInvalidL1InfoTreeIndex = errors.New("l1 info tree index is invalid")
|
| 90 |
-
|
| 91 |
// EXECUTOR ERRORS
|
| 92 |
// ===============
|
| 93 |
|
|
@@ -327,67 +322,6 @@
|
|
| 327 |
// ErrExecutorErrorSMMainInvalidTxStatusError indicates that the TX has an invalid status-error combination
|
| 328 |
ErrExecutorErrorSMMainInvalidTxStatusError = errors.New("tx has an invalid status-error combination")
|
| 329 |
|
| 330 |
-
// Start of V3 errors
|
| 331 |
-
|
| 332 |
-
// ErrExecutorErrorInvalidPreviousL1InfoTreeRoot indicates that the input parameter previous_l1_info_tree_root is invalid
|
| 333 |
-
ErrExecutorErrorInvalidPreviousL1InfoTreeRoot = errors.New("previous_l1_info_tree_root is invalid")
|
| 334 |
-
// ErrExecutorErrorInvalidForcedHashData indicates that the input parameter forced_hash_data is invalid
|
| 335 |
-
ErrExecutorErrorInvalidForcedHashData = errors.New("forced_hash_data is invalid")
|
| 336 |
-
// ErrExecutorErrorInvalidForcedDataGlobalExitRoot indicates that the input parameter forced_data.global_exit_root is invalid
|
| 337 |
-
ErrExecutorErrorInvalidForcedDataGlobalExitRoot = errors.New("forced_data.global_exit_root is invalid")
|
| 338 |
-
// ErrExecutorErrorInvalidForcedDataBlockHashL1 indicates that the input parameter forced_data.block_hash_l1 is invalid
|
| 339 |
-
ErrExecutorErrorInvalidForcedDataBlockHashL1 = errors.New("forced_data.block_hash_l1 is invalid")
|
| 340 |
-
// ErrExecutorErrorInvalidL1DataV3InitialHistoricRoot indicates that the input parameter L1 Data initiali_historic_root is invalid
|
| 341 |
-
ErrExecutorErrorInvalidL1DataV3InitialHistoricRoot = errors.New("L1 Data initiali_historic_root is invalid")
|
| 342 |
-
// ErrExecutorErrorInvalidOldBlobStateRoot indicates that the input parameter old_blob_state_root is invalid
|
| 343 |
-
ErrExecutorErrorInvalidOldBlobStateRoot = errors.New("old_blob_state_root is invalid")
|
| 344 |
-
// ErrExecutorErrorInvalidOldBlobAccInputHash indicates that the input parameter old_blob_acc_input_hash is invalid
|
| 345 |
-
ErrExecutorErrorInvalidOldBlobAccInputHash = errors.New("old_blob_acc_input_hash is invalid")
|
| 346 |
-
// ErrExecutorErrorInvalidLastL1InfoTreeRoot indicates that the input parameter last_l1_info_tree_root is invalid
|
| 347 |
-
ErrExecutorErrorInvalidLastL1InfoTreeRoot = errors.New("last_l1_info_tree_root is invalid")
|
| 348 |
-
// ErrExecutorErrorInvalidNewBlobStateRoot indicates that the input parameter new_blob_state_root is invalid
|
| 349 |
-
ErrExecutorErrorInvalidNewBlobStateRoot = errors.New("new_blob_state_root is invalid")
|
| 350 |
-
// ErrExecutorErrorInvalidNewBlobAccInputHash indicates that the input parameter new_blob_acc_input_hash is invalid
|
| 351 |
-
ErrExecutorErrorInvalidNewBlobAccInputHash = errors.New("new_blob_acc_input_hash is invalid")
|
| 352 |
-
// ErrExecutorErrorInvalidBlobData indicates that the input parameter blob_data is invalid
|
| 353 |
-
ErrExecutorErrorInvalidBlobData = errors.New("blob_data is invalid")
|
| 354 |
-
// ErrExecutorErrorInvalidZKGasLimit indicates that the input parameter zk_gas_limit is invalid
|
| 355 |
-
ErrExecutorErrorInvalidZKGasLimit = errors.New("zk_gas_limit is invalid")
|
| 356 |
-
// ErrExecutorErrorInvalidPointZ indicates that the input parameter point_z is invalid
|
| 357 |
-
ErrExecutorErrorInvalidPointZ = errors.New("point_z is invalid")
|
| 358 |
-
// ErrExecutorErrorInvalidPointY indicates that the input parameter point_y is invalid
|
| 359 |
-
ErrExecutorErrorInvalidPointY = errors.New("point_y is invalid")
|
| 360 |
-
// ErrExecutorErrorSMMainPointZMismatch indicates that the input parameter point_z is different from the one calculated by the executor
|
| 361 |
-
ErrExecutorErrorSMMainPointZMismatch = errors.New("point_z mismatch")
|
| 362 |
-
// ErrExecutorErrorSMMainBlobL2HashDataMismatch indicates that the input parameter blob L2 data hash is different from the one calculated by the executor
|
| 363 |
-
ErrExecutorErrorSMMainBlobL2HashDataMismatch = errors.New("blob L2 hash data mismatch")
|
| 364 |
-
// ErrExecutorErrorSMMainBatchHashDataMismatch indicates that the input parameter batch data hash is different from the one calculated by the executor
|
| 365 |
-
ErrExecutorErrorSMMainBatchHashDataMismatch = errors.New("batch hash data mismatch")
|
| 366 |
-
// ErrExecutorErrorSMMainInvalidBlobType indicates that the input parameter blob type is invalid
|
| 367 |
-
ErrExecutorErrorSMMainInvalidBlobType = errors.New("invalid blob type")
|
| 368 |
-
// ErrExecutorErrorSMMainUnrestoredSavedContext indicates that at least one saved context was not restored before finishing the execution
|
| 369 |
-
ErrExecutorErrorSMMainUnrestoredSavedContext = errors.New("unrestored saved context")
|
| 370 |
-
// ErrExecutorErrorSMMainInvalidMemoryCtx indicates that the memory context polynomial was assigned an invalid value
|
| 371 |
-
ErrExecutorErrorSMMainInvalidMemoryCtx = errors.New("invalid memory ctx")
|
| 372 |
-
|
| 373 |
-
// ROM BLOB ERRORS
|
| 374 |
-
// ===============
|
| 375 |
-
|
| 376 |
-
// ErrROMBlobInvalidParsing indicates that has been an error while parsing the blob data
|
| 377 |
-
ErrROMBlobInvalidParsing = errors.New("error while parsing the blob data")
|
| 378 |
-
// ErrROMBlobInvalidMSBByte indicates that the MSB on one field element is different than zero (only for blob_type = 1)
|
| 379 |
-
ErrROMBlobInvalidMSBByte = errors.New("MSB on one field element is different than zero")
|
| 380 |
-
// ErrROMBlobInvalidZKGasLimit not enough zk_gas_limit supplied to pay for batches proofs
|
| 381 |
-
ErrROMBlobInvalidZKGasLimit = errors.New("not enough zk_gas_limit supplied to pay for batches proofs")
|
| 382 |
-
// ErrROMBlobInvalidBlobType blob_type not supported
|
| 383 |
-
ErrROMBlobInvalidBlobType = errors.New("blob_type not supported")
|
| 384 |
-
// ErrROMBlobInvalidCompressionType compression type not supported
|
| 385 |
-
ErrROMBlobInvalidCompressionType = errors.New("compression type not supported")
|
| 386 |
-
// ErrROMBlobInvalidForcedBatches fblobtype = 2 and numBatches > 1
|
| 387 |
-
ErrROMBlobInvalidForcedBatches = errors.New("fblobtype = 2 and numBatches > 1")
|
| 388 |
-
// ErrROMBlobInvalidTotalBodyLen totalBodyLen != blobDataLen - 1 (byte compression) - 4 (bytes totalBodyLen)
|
| 389 |
-
ErrROMBlobInvalidTotalBodyLen = errors.New("totalBodyLen != blobDataLen - 1 (byte compression) - 4 (bytes totalBodyLen)")
|
| 390 |
-
|
| 391 |
// GRPC ERRORS
|
| 392 |
// ===========
|
| 393 |
|
|
|
|
| 83 |
// ErrInvalidTxChangeL2BlockMinTimestamp indicates that the change l2 block transaction has trigger an error while executing
|
| 84 |
ErrInvalidTxChangeL2BlockMinTimestamp = errors.New("indicates that the change l2 block transaction has trigger an error while executing (min timestamp)")
|
| 85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
// EXECUTOR ERRORS
|
| 87 |
// ===============
|
| 88 |
|
|
|
|
| 322 |
// ErrExecutorErrorSMMainInvalidTxStatusError indicates that the TX has an invalid status-error combination
|
| 323 |
ErrExecutorErrorSMMainInvalidTxStatusError = errors.New("tx has an invalid status-error combination")
|
| 324 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
// GRPC ERRORS
|
| 326 |
// ===========
|
| 327 |
|
|
@@ -32,18 +32,17 @@
|
|
| 32 |
type State struct {
|
| 33 |
cfg Config
|
| 34 |
storage
|
| 35 |
-
executorClient
|
| 36 |
-
tree
|
| 37 |
-
eventLog
|
| 38 |
-
l1InfoTree
|
| 39 |
-
l1InfoTreeRecursive *l1infotree.L1InfoTreeRecursive
|
| 40 |
|
| 41 |
newL2BlockEvents chan NewL2BlockEvent
|
| 42 |
newL2BlockEventHandlers []NewL2BlockEventHandler
|
| 43 |
}
|
| 44 |
|
| 45 |
// NewState creates a new State
|
| 46 |
-
func NewState(cfg Config, storage storage, executorClient executor.ExecutorServiceClient, stateTree *merkletree.StateTree, eventLog *event.EventLog, mt *l1infotree.L1InfoTree
|
| 47 |
var once sync.Once
|
| 48 |
once.Do(func() {
|
| 49 |
metrics.Register()
|
|
@@ -58,7 +57,6 @@
|
|
| 58 |
newL2BlockEvents: make(chan NewL2BlockEvent, newL2BlockEventBufferSize),
|
| 59 |
newL2BlockEventHandlers: []NewL2BlockEventHandler{},
|
| 60 |
l1InfoTree: mt,
|
| 61 |
-
l1InfoTreeRecursive: mtr,
|
| 62 |
}
|
| 63 |
|
| 64 |
return state
|
|
|
|
| 32 |
type State struct {
|
| 33 |
cfg Config
|
| 34 |
storage
|
| 35 |
+
executorClient executor.ExecutorServiceClient
|
| 36 |
+
tree *merkletree.StateTree
|
| 37 |
+
eventLog *event.EventLog
|
| 38 |
+
l1InfoTree *l1infotree.L1InfoTree
|
|
|
|
| 39 |
|
| 40 |
newL2BlockEvents chan NewL2BlockEvent
|
| 41 |
newL2BlockEventHandlers []NewL2BlockEventHandler
|
| 42 |
}
|
| 43 |
|
| 44 |
// NewState creates a new State
|
| 45 |
+
func NewState(cfg Config, storage storage, executorClient executor.ExecutorServiceClient, stateTree *merkletree.StateTree, eventLog *event.EventLog, mt *l1infotree.L1InfoTree) *State {
|
| 46 |
var once sync.Once
|
| 47 |
once.Do(func() {
|
| 48 |
metrics.Register()
|
|
|
|
| 57 |
newL2BlockEvents: make(chan NewL2BlockEvent, newL2BlockEventBufferSize),
|
| 58 |
newL2BlockEventHandlers: []NewL2BlockEventHandler{},
|
| 59 |
l1InfoTree: mt,
|
|
|
|
| 60 |
}
|
| 61 |
|
| 62 |
return state
|
|
@@ -28,7 +28,7 @@
|
|
| 28 |
ctx := context.Background()
|
| 29 |
mockStorage := mocks.NewStorageMock(t)
|
| 30 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 31 |
-
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil
|
| 32 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 33 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 34 |
require.NoError(t, err)
|
|
@@ -74,7 +74,7 @@
|
|
| 74 |
ctx := context.Background()
|
| 75 |
mockStorage := mocks.NewStorageMock(t)
|
| 76 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 77 |
-
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil
|
| 78 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 79 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 80 |
require.NoError(t, err)
|
|
|
|
| 28 |
ctx := context.Background()
|
| 29 |
mockStorage := mocks.NewStorageMock(t)
|
| 30 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 31 |
+
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil)
|
| 32 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 33 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 34 |
require.NoError(t, err)
|
|
|
|
| 74 |
ctx := context.Background()
|
| 75 |
mockStorage := mocks.NewStorageMock(t)
|
| 76 |
mockExecutor := mocks.NewExecutorServiceClientMock(t)
|
| 77 |
+
testState := state.NewState(stateCfg, mockStorage, mockExecutor, nil, nil, nil)
|
| 78 |
mockStorage.EXPECT().Begin(ctx).Return(mocks.NewDbTxMock(t), nil)
|
| 79 |
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 80 |
require.NoError(t, err)
|
|
@@ -53,7 +53,7 @@
|
|
| 53 |
panic(err)
|
| 54 |
}
|
| 55 |
|
| 56 |
-
zkProverURI := testutils.GetEnv("ZKPROVER_URI", "
|
| 57 |
|
| 58 |
executorServerConfig := executor.Config{URI: fmt.Sprintf("%s:50071", zkProverURI), MaxGRPCMessageSize: 100000000}
|
| 59 |
ExecutorClient, executorClientConn, executorCancel = executor.NewExecutorClient(ctx, executorServerConfig)
|
|
@@ -76,11 +76,7 @@
|
|
| 76 |
if err != nil {
|
| 77 |
panic(err)
|
| 78 |
}
|
| 79 |
-
|
| 80 |
-
if err != nil {
|
| 81 |
-
panic(err)
|
| 82 |
-
}
|
| 83 |
-
return state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), ExecutorClient, stateTree, eventLog, mt, mtr)
|
| 84 |
}
|
| 85 |
|
| 86 |
func InitOrResetDB(cfg db.Config) {
|
|
|
|
| 53 |
panic(err)
|
| 54 |
}
|
| 55 |
|
| 56 |
+
zkProverURI := testutils.GetEnv("ZKPROVER_URI", "zkevm-prover")
|
| 57 |
|
| 58 |
executorServerConfig := executor.Config{URI: fmt.Sprintf("%s:50071", zkProverURI), MaxGRPCMessageSize: 100000000}
|
| 59 |
ExecutorClient, executorClientConn, executorCancel = executor.NewExecutorClient(ctx, executorServerConfig)
|
|
|
|
| 76 |
if err != nil {
|
| 77 |
panic(err)
|
| 78 |
}
|
| 79 |
+
return state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), ExecutorClient, stateTree, eventLog, mt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
}
|
| 81 |
|
| 82 |
func InitOrResetDB(cfg db.Config) {
|
|
@@ -98,11 +98,9 @@
|
|
| 98 |
if len(txs) > 0 {
|
| 99 |
// Generate batchdata from the txs in the test and compared with the vector
|
| 100 |
l2block := state.L2BlockRaw{
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
},
|
| 105 |
-
Transactions: txs,
|
| 106 |
}
|
| 107 |
|
| 108 |
batch := state.BatchRawV2{
|
|
|
|
| 98 |
if len(txs) > 0 {
|
| 99 |
// Generate batchdata from the txs in the test and compared with the vector
|
| 100 |
l2block := state.L2BlockRaw{
|
| 101 |
+
DeltaTimestamp: uint32(timestampLimit.Uint64()),
|
| 102 |
+
IndexL1InfoTree: testCase.Txs[0].IndexL1InfoTree,
|
| 103 |
+
Transactions: txs,
|
|
|
|
|
|
|
| 104 |
}
|
| 105 |
|
| 106 |
batch := state.BatchRawV2{
|
|
@@ -78,7 +78,15 @@
|
|
| 78 |
var effectivePercentage []uint8
|
| 79 |
for i := 0; i <= count; i++ {
|
| 80 |
txsToEncode = append(txsToEncode, *l2Block.Transactions()[i])
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
log.Debugf("trace will reprocess tx: %v", l2Block.Transactions()[i].Hash().String())
|
| 83 |
}
|
| 84 |
|
|
@@ -307,7 +315,7 @@
|
|
| 307 |
return nil, err
|
| 308 |
} else if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 309 |
err = executor.ExecutorErr(processBatchResponseV2.Error)
|
| 310 |
-
s.eventLog.
|
| 311 |
return nil, err
|
| 312 |
}
|
| 313 |
|
|
|
|
| 78 |
var effectivePercentage []uint8
|
| 79 |
for i := 0; i <= count; i++ {
|
| 80 |
txsToEncode = append(txsToEncode, *l2Block.Transactions()[i])
|
| 81 |
+
txGasPrice := tx.GasPrice()
|
| 82 |
+
effectiveGasPrice := receipt.EffectiveGasPrice
|
| 83 |
+
egpPercentage, err := CalculateEffectiveGasPricePercentage(txGasPrice, effectiveGasPrice)
|
| 84 |
+
if errors.Is(err, ErrEffectiveGasPriceEmpty) {
|
| 85 |
+
egpPercentage = MaxEffectivePercentage
|
| 86 |
+
} else if err != nil {
|
| 87 |
+
return nil, err
|
| 88 |
+
}
|
| 89 |
+
effectivePercentage = append(effectivePercentage, egpPercentage)
|
| 90 |
log.Debugf("trace will reprocess tx: %v", l2Block.Transactions()[i].Hash().String())
|
| 91 |
}
|
| 92 |
|
|
|
|
| 315 |
return nil, err
|
| 316 |
} else if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 317 |
err = executor.ExecutorErr(processBatchResponseV2.Error)
|
| 318 |
+
s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2)
|
| 319 |
return nil, err
|
| 320 |
}
|
| 321 |
|
|
@@ -244,6 +244,7 @@
|
|
| 244 |
imStateRoots := make([]common.Hash, 0, numTxs)
|
| 245 |
var receipt *types.Receipt
|
| 246 |
|
|
|
|
| 247 |
for i, txResponse := range l2Block.TransactionResponses {
|
| 248 |
// if the transaction has an intrinsic invalid tx error it means
|
| 249 |
// the transaction has not changed the state, so we don't store it
|
|
@@ -263,9 +264,10 @@
|
|
| 263 |
|
| 264 |
storeTxsEGPData = append(storeTxsEGPData, storeTxEGPData)
|
| 265 |
|
| 266 |
-
receipt = GenerateReceipt(header.Number, txResponse, uint(
|
| 267 |
receipts = append(receipts, receipt)
|
| 268 |
imStateRoots = append(imStateRoots, txResp.StateRoot)
|
|
|
|
| 269 |
}
|
| 270 |
|
| 271 |
// Create block to be able to calculate its hash
|
|
@@ -536,6 +538,7 @@
|
|
| 536 |
TimestampLimit: l2Block.Time(),
|
| 537 |
SkipFirstChangeL2Block: cFalse,
|
| 538 |
SkipWriteBlockInfoRoot: cTrue,
|
|
|
|
| 539 |
}
|
| 540 |
if noZKEVMCounters {
|
| 541 |
processBatchRequestV2.NoCounters = cTrue
|
|
@@ -600,7 +603,7 @@
|
|
| 600 |
|
| 601 |
if err == nil && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 602 |
err = executor.ExecutorErr(processBatchResponseV2.Error)
|
| 603 |
-
s.eventLog.
|
| 604 |
return nil, err
|
| 605 |
}
|
| 606 |
|
|
@@ -1014,6 +1017,7 @@
|
|
| 1014 |
TimestampLimit: uint64(time.Now().Unix()),
|
| 1015 |
SkipFirstChangeL2Block: cTrue,
|
| 1016 |
SkipWriteBlockInfoRoot: cTrue,
|
|
|
|
| 1017 |
}
|
| 1018 |
|
| 1019 |
log.Debugf("EstimateGas[processBatchRequestV2.From]: %v", processBatchRequestV2.From)
|
|
@@ -1040,7 +1044,7 @@
|
|
| 1040 |
}
|
| 1041 |
if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 1042 |
err = executor.ExecutorErr(processBatchResponseV2.Error)
|
| 1043 |
-
s.eventLog.
|
| 1044 |
return false, false, gasUsed, nil, err
|
| 1045 |
}
|
| 1046 |
if processBatchResponseV2.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR {
|
|
|
|
| 244 |
imStateRoots := make([]common.Hash, 0, numTxs)
|
| 245 |
var receipt *types.Receipt
|
| 246 |
|
| 247 |
+
txIndex := 0
|
| 248 |
for i, txResponse := range l2Block.TransactionResponses {
|
| 249 |
// if the transaction has an intrinsic invalid tx error it means
|
| 250 |
// the transaction has not changed the state, so we don't store it
|
|
|
|
| 264 |
|
| 265 |
storeTxsEGPData = append(storeTxsEGPData, storeTxEGPData)
|
| 266 |
|
| 267 |
+
receipt = GenerateReceipt(header.Number, txResponse, uint(txIndex), forkID)
|
| 268 |
receipts = append(receipts, receipt)
|
| 269 |
imStateRoots = append(imStateRoots, txResp.StateRoot)
|
| 270 |
+
txIndex++
|
| 271 |
}
|
| 272 |
|
| 273 |
// Create block to be able to calculate its hash
|
|
|
|
| 538 |
TimestampLimit: l2Block.Time(),
|
| 539 |
SkipFirstChangeL2Block: cFalse,
|
| 540 |
SkipWriteBlockInfoRoot: cTrue,
|
| 541 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 542 |
}
|
| 543 |
if noZKEVMCounters {
|
| 544 |
processBatchRequestV2.NoCounters = cTrue
|
|
|
|
| 603 |
|
| 604 |
if err == nil && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 605 |
err = executor.ExecutorErr(processBatchResponseV2.Error)
|
| 606 |
+
s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2)
|
| 607 |
return nil, err
|
| 608 |
}
|
| 609 |
|
|
|
|
| 1017 |
TimestampLimit: uint64(time.Now().Unix()),
|
| 1018 |
SkipFirstChangeL2Block: cTrue,
|
| 1019 |
SkipWriteBlockInfoRoot: cTrue,
|
| 1020 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 1021 |
}
|
| 1022 |
|
| 1023 |
log.Debugf("EstimateGas[processBatchRequestV2.From]: %v", processBatchRequestV2.From)
|
|
|
|
| 1044 |
}
|
| 1045 |
if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR {
|
| 1046 |
err = executor.ExecutorErr(processBatchResponseV2.Error)
|
| 1047 |
+
s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2)
|
| 1048 |
return false, false, gasUsed, nil, err
|
| 1049 |
}
|
| 1050 |
if processBatchResponseV2.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR {
|
|
@@ -15,25 +15,23 @@
|
|
| 15 |
|
| 16 |
// ProcessRequest represents the request of a batch process.
|
| 17 |
type ProcessRequest struct {
|
| 18 |
-
BatchNumber
|
| 19 |
-
GlobalExitRoot_V1
|
| 20 |
-
L1InfoRoot_V2
|
| 21 |
-
L1InfoTreeData_V2
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
PreviousL1InfoTreeRoot_V3 common.Hash
|
| 36 |
-
PreviousL1InfoTreeIndex_V3 uint32
|
| 37 |
}
|
| 38 |
|
| 39 |
// L1DataV2 represents the L1InfoTree data used in ProcessRequest.L1InfoTreeData_V2 parameter
|
|
@@ -44,15 +42,6 @@
|
|
| 44 |
SmtProof [][]byte
|
| 45 |
}
|
| 46 |
|
| 47 |
-
// L1DataV3 represents the L1InfoTree data used in ProcessRequest.L1InfoTreeData_V3 parameter
|
| 48 |
-
type L1DataV3 struct {
|
| 49 |
-
GlobalExitRoot common.Hash
|
| 50 |
-
BlockHashL1 common.Hash
|
| 51 |
-
MinTimestamp uint64
|
| 52 |
-
SmtProofPreviousIndex [][]byte
|
| 53 |
-
InitialHistoricRoot common.Hash
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
// ProcessBatchResponse represents the response of a batch process.
|
| 57 |
type ProcessBatchResponse struct {
|
| 58 |
NewStateRoot common.Hash
|
|
@@ -62,25 +51,21 @@
|
|
| 62 |
UsedZkCounters ZKCounters
|
| 63 |
ReservedZkCounters ZKCounters
|
| 64 |
// TransactionResponses_V1 []*ProcessTransactionResponse
|
| 65 |
-
BlockResponses
|
| 66 |
-
ExecutorError
|
| 67 |
-
ReadWriteAddresses
|
| 68 |
-
IsRomLevelError
|
| 69 |
-
IsExecutorLevelError
|
| 70 |
-
IsRomOOCError
|
| 71 |
-
FlushID
|
| 72 |
-
StoredFlushID
|
| 73 |
-
ProverID
|
| 74 |
-
GasUsed_V2
|
| 75 |
-
SMTKeys_V2
|
| 76 |
-
ProgramKeys_V2
|
| 77 |
-
ForkID
|
| 78 |
-
InvalidBatch_V2
|
| 79 |
-
RomError_V2
|
| 80 |
-
OldStateRoot_V2 common.Hash
|
| 81 |
-
NewLastTimestamp_V3 uint64
|
| 82 |
-
CurrentL1InfoTreeRoot_V3 common.Hash
|
| 83 |
-
CurrentL1InfoTreeIndex_V3 uint32
|
| 84 |
}
|
| 85 |
|
| 86 |
// ProcessBlockResponse represents the response of a block
|
|
|
|
| 15 |
|
| 16 |
// ProcessRequest represents the request of a batch process.
|
| 17 |
type ProcessRequest struct {
|
| 18 |
+
BatchNumber uint64
|
| 19 |
+
GlobalExitRoot_V1 common.Hash
|
| 20 |
+
L1InfoRoot_V2 common.Hash
|
| 21 |
+
L1InfoTreeData_V2 map[uint32]L1DataV2
|
| 22 |
+
OldStateRoot common.Hash
|
| 23 |
+
OldAccInputHash common.Hash
|
| 24 |
+
Transactions []byte
|
| 25 |
+
Coinbase common.Address
|
| 26 |
+
ForcedBlockHashL1 common.Hash
|
| 27 |
+
Timestamp_V1 time.Time
|
| 28 |
+
TimestampLimit_V2 uint64
|
| 29 |
+
Caller metrics.CallerLabel
|
| 30 |
+
SkipFirstChangeL2Block_V2 bool
|
| 31 |
+
SkipWriteBlockInfoRoot_V2 bool
|
| 32 |
+
SkipVerifyL1InfoRoot_V2 bool
|
| 33 |
+
ForkID uint64
|
| 34 |
+
ExecutionMode uint64
|
|
|
|
|
|
|
| 35 |
}
|
| 36 |
|
| 37 |
// L1DataV2 represents the L1InfoTree data used in ProcessRequest.L1InfoTreeData_V2 parameter
|
|
|
|
| 42 |
SmtProof [][]byte
|
| 43 |
}
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
// ProcessBatchResponse represents the response of a batch process.
|
| 46 |
type ProcessBatchResponse struct {
|
| 47 |
NewStateRoot common.Hash
|
|
|
|
| 51 |
UsedZkCounters ZKCounters
|
| 52 |
ReservedZkCounters ZKCounters
|
| 53 |
// TransactionResponses_V1 []*ProcessTransactionResponse
|
| 54 |
+
BlockResponses []*ProcessBlockResponse
|
| 55 |
+
ExecutorError error
|
| 56 |
+
ReadWriteAddresses map[common.Address]*InfoReadWrite
|
| 57 |
+
IsRomLevelError bool
|
| 58 |
+
IsExecutorLevelError bool
|
| 59 |
+
IsRomOOCError bool
|
| 60 |
+
FlushID uint64
|
| 61 |
+
StoredFlushID uint64
|
| 62 |
+
ProverID string
|
| 63 |
+
GasUsed_V2 uint64
|
| 64 |
+
SMTKeys_V2 []merkletree.Key
|
| 65 |
+
ProgramKeys_V2 []merkletree.Key
|
| 66 |
+
ForkID uint64
|
| 67 |
+
InvalidBatch_V2 bool
|
| 68 |
+
RomError_V2 error
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
}
|
| 70 |
|
| 71 |
// ProcessBlockResponse represents the response of a block
|
|
@@ -19,9 +19,9 @@
|
|
| 19 |
// NewProcessorL1InitialSequenceBatchesElderberry returns instance of a processor for InitialSequenceBatchesOrder
|
| 20 |
func NewProcessorL1InitialSequenceBatchesElderberry(previousProcessor actions.L1EventProcessor) *ProcessorL1InitialSequenceBatchesElderberry {
|
| 21 |
return &ProcessorL1InitialSequenceBatchesElderberry{
|
| 22 |
-
ProcessorBase:
|
| 23 |
-
[]etherman.EventOrder{etherman.InitialSequenceBatchesOrder},
|
| 24 |
-
actions.ForksIdOnlyElderberry
|
| 25 |
previousProcessor: previousProcessor,
|
| 26 |
}
|
| 27 |
}
|
|
|
|
| 19 |
// NewProcessorL1InitialSequenceBatchesElderberry returns instance of a processor for InitialSequenceBatchesOrder
|
| 20 |
func NewProcessorL1InitialSequenceBatchesElderberry(previousProcessor actions.L1EventProcessor) *ProcessorL1InitialSequenceBatchesElderberry {
|
| 21 |
return &ProcessorL1InitialSequenceBatchesElderberry{
|
| 22 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1InitialSequenceBatchesElderberry]{
|
| 23 |
+
SupportedEvent: []etherman.EventOrder{etherman.InitialSequenceBatchesOrder},
|
| 24 |
+
SupportedForkdIds: &actions.ForksIdOnlyElderberry},
|
| 25 |
previousProcessor: previousProcessor,
|
| 26 |
}
|
| 27 |
}
|
|
@@ -3,7 +3,6 @@
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
| 6 |
-
"fmt"
|
| 7 |
"time"
|
| 8 |
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
|
@@ -40,9 +39,9 @@
|
|
| 40 |
// NewProcessorL1SequenceBatchesElderberry returns instance of a processor for SequenceBatchesOrder
|
| 41 |
func NewProcessorL1SequenceBatchesElderberry(previousProcessor PreviousProcessor, state StateL1SequenceBatchesElderberry) *ProcessorL1SequenceBatchesElderberry {
|
| 42 |
return &ProcessorL1SequenceBatchesElderberry{
|
| 43 |
-
ProcessorBase:
|
| 44 |
-
[]etherman.EventOrder{etherman.SequenceBatchesOrder},
|
| 45 |
-
actions.ForksIdOnlyElderberry
|
| 46 |
previousProcessor: previousProcessor,
|
| 47 |
state: state,
|
| 48 |
}
|
|
@@ -60,58 +59,12 @@
|
|
| 60 |
|
| 61 |
sbatch := l1Block.SequencedBatches[order.Pos][0]
|
| 62 |
|
|
|
|
| 63 |
if sbatch.SequencedBatchElderberryData == nil {
|
| 64 |
-
log.
|
| 65 |
-
|
|
|
|
| 66 |
}
|
| 67 |
-
// We need to check that the sequence match
|
| 68 |
-
err := g.sanityCheckExpectedSequence(sbatch.SequencedBatchElderberryData.InitSequencedBatchNumber, dbTx)
|
| 69 |
-
if err != nil {
|
| 70 |
-
return err
|
| 71 |
-
}
|
| 72 |
-
// We known that the MaxSequenceTimestamp is the same for all the batches so we can use the first one
|
| 73 |
-
err = g.previousProcessor.ProcessSequenceBatches(ctx, l1Block.SequencedBatches[order.Pos], l1Block.BlockNumber, time.Unix(int64(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp), 0), dbTx)
|
| 74 |
-
// The last L2block timestamp must match MaxSequenceTimestamp
|
| 75 |
-
if err != nil {
|
| 76 |
-
return err
|
| 77 |
-
}
|
| 78 |
-
// It checks the timestamp of the last L2 block, but it's just log an error instead of refusing the event
|
| 79 |
-
_ = g.sanityCheckTstampLastL2Block(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp, dbTx)
|
| 80 |
-
return nil
|
| 81 |
-
}
|
| 82 |
-
|
| 83 |
-
func (g *ProcessorL1SequenceBatchesElderberry) sanityCheckExpectedSequence(initialBatchNumber uint64, dbTx pgx.Tx) error {
|
| 84 |
-
// We need to check that the sequence match
|
| 85 |
-
lastVirtualBatchNum, err := g.state.GetLastVirtualBatchNum(context.Background(), dbTx)
|
| 86 |
-
if err != nil {
|
| 87 |
-
log.Errorf("Error getting last virtual batch number: %s", err)
|
| 88 |
-
return err
|
| 89 |
-
}
|
| 90 |
-
if lastVirtualBatchNum != initialBatchNumber {
|
| 91 |
-
log.Errorf("The last virtual batch number is not the expected one. Expected: %d (last on DB), got: %d (L1 event)", lastVirtualBatchNum+1, initialBatchNumber)
|
| 92 |
-
return fmt.Errorf("the last virtual batch number is not the expected one. Expected: %d (last on DB), got: %d (L1 event) err:%w", lastVirtualBatchNum+1, initialBatchNumber, ErrInvalidInitialBatchNumber)
|
| 93 |
-
}
|
| 94 |
-
return nil
|
| 95 |
-
}
|
| 96 |
|
| 97 |
-
|
| 98 |
-
lastVirtualBatchNum, err := g.state.GetLastVirtualBatchNum(context.Background(), dbTx)
|
| 99 |
-
if err != nil {
|
| 100 |
-
log.Errorf("Error getting last virtual batch number: %s", err)
|
| 101 |
-
return err
|
| 102 |
-
}
|
| 103 |
-
lastL2Block, err := g.state.GetLastL2BlockByBatchNumber(context.Background(), lastVirtualBatchNum, dbTx)
|
| 104 |
-
if err != nil {
|
| 105 |
-
log.Errorf("Error getting last virtual batch number: %s", err)
|
| 106 |
-
return err
|
| 107 |
-
}
|
| 108 |
-
if lastL2Block == nil {
|
| 109 |
-
//TODO: find the previous batch until we find a L2 block to check the timestamp
|
| 110 |
-
return nil
|
| 111 |
-
}
|
| 112 |
-
if uint64(lastL2Block.ReceivedAt.Unix()) > timeLimit {
|
| 113 |
-
log.Errorf("The last L2 block timestamp can't be greater than timeLimit. Expected: %d (L1 event), got: %d (last L2Block)", timeLimit, lastL2Block.ReceivedAt.Unix())
|
| 114 |
-
return fmt.Errorf("wrong timestamp of last L2 block timestamp with L1 event timestamp")
|
| 115 |
-
}
|
| 116 |
-
return nil
|
| 117 |
}
|
|
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
|
|
|
| 6 |
"time"
|
| 7 |
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
|
|
|
| 39 |
// NewProcessorL1SequenceBatchesElderberry returns instance of a processor for SequenceBatchesOrder
|
| 40 |
func NewProcessorL1SequenceBatchesElderberry(previousProcessor PreviousProcessor, state StateL1SequenceBatchesElderberry) *ProcessorL1SequenceBatchesElderberry {
|
| 41 |
return &ProcessorL1SequenceBatchesElderberry{
|
| 42 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1SequenceBatchesElderberry]{
|
| 43 |
+
SupportedEvent: []etherman.EventOrder{etherman.SequenceBatchesOrder},
|
| 44 |
+
SupportedForkdIds: &actions.ForksIdOnlyElderberry},
|
| 45 |
previousProcessor: previousProcessor,
|
| 46 |
state: state,
|
| 47 |
}
|
|
|
|
| 59 |
|
| 60 |
sbatch := l1Block.SequencedBatches[order.Pos][0]
|
| 61 |
|
| 62 |
+
executionTime := l1Block.ReceivedAt
|
| 63 |
if sbatch.SequencedBatchElderberryData == nil {
|
| 64 |
+
log.Warnf("No elderberry sequenced batch data for batch %d", sbatch.BatchNumber)
|
| 65 |
+
} else {
|
| 66 |
+
executionTime = time.Unix(int64(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp), 0)
|
| 67 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
+
return g.previousProcessor.ProcessSequenceBatches(ctx, l1Block.SequencedBatches[order.Pos], l1Block.BlockNumber, executionTime, dbTx)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
}
|
|
@@ -24,9 +24,9 @@
|
|
| 24 |
// NewProcessorL1InfoTreeUpdate new processor for GlobalExitRootsOrder
|
| 25 |
func NewProcessorL1InfoTreeUpdate(state stateProcessorL1InfoTreeInterface) *ProcessorL1InfoTreeUpdate {
|
| 26 |
return &ProcessorL1InfoTreeUpdate{
|
| 27 |
-
ProcessorBase:
|
| 28 |
-
[]etherman.EventOrder{etherman.L1InfoTreeOrder},
|
| 29 |
-
actions.
|
| 30 |
state: state}
|
| 31 |
}
|
| 32 |
|
|
|
|
| 24 |
// NewProcessorL1InfoTreeUpdate new processor for GlobalExitRootsOrder
|
| 25 |
func NewProcessorL1InfoTreeUpdate(state stateProcessorL1InfoTreeInterface) *ProcessorL1InfoTreeUpdate {
|
| 26 |
return &ProcessorL1InfoTreeUpdate{
|
| 27 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1InfoTreeUpdate]{
|
| 28 |
+
SupportedEvent: []etherman.EventOrder{etherman.L1InfoTreeOrder},
|
| 29 |
+
SupportedForkdIds: &actions.ForksIdAll},
|
| 30 |
state: state}
|
| 31 |
}
|
| 32 |
|
|
@@ -45,7 +45,7 @@
|
|
| 45 |
if err != nil {
|
| 46 |
panic(err)
|
| 47 |
}
|
| 48 |
-
testState := state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), nil, nil, nil, mt
|
| 49 |
|
| 50 |
sut := NewProcessorL1InfoTreeUpdate(testState)
|
| 51 |
l1infotree := etherman.GlobalExitRoot{
|
|
|
|
| 45 |
if err != nil {
|
| 46 |
panic(err)
|
| 47 |
}
|
| 48 |
+
testState := state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(stateCfg, stateDb), nil, nil, nil, mt)
|
| 49 |
|
| 50 |
sut := NewProcessorL1InfoTreeUpdate(testState)
|
| 51 |
l1infotree := etherman.GlobalExitRoot{
|
|
@@ -55,9 +55,9 @@
|
|
| 55 |
timeProvider syncCommon.TimeProvider,
|
| 56 |
halter syncinterfaces.CriticalErrorHandler) *ProcessorL1SequenceBatchesEtrog {
|
| 57 |
return &ProcessorL1SequenceBatchesEtrog{
|
| 58 |
-
ProcessorBase:
|
| 59 |
-
[]etherman.EventOrder{etherman.SequenceBatchesOrder, etherman.InitialSequenceBatchesOrder},
|
| 60 |
-
actions.ForksIdOnlyEtrog
|
| 61 |
state: state,
|
| 62 |
sync: sync,
|
| 63 |
timeProvider: timeProvider,
|
|
@@ -287,8 +287,8 @@
|
|
| 287 |
|
| 288 |
// Reset trusted state
|
| 289 |
previousBatchNumber := batch.BatchNumber - 1
|
| 290 |
-
if tBatch.
|
| 291 |
-
log.
|
| 292 |
} else {
|
| 293 |
log.Warnf("missmatch in trusted state detected, discarding batches until batchNum %d", previousBatchNumber)
|
| 294 |
}
|
|
|
|
| 55 |
timeProvider syncCommon.TimeProvider,
|
| 56 |
halter syncinterfaces.CriticalErrorHandler) *ProcessorL1SequenceBatchesEtrog {
|
| 57 |
return &ProcessorL1SequenceBatchesEtrog{
|
| 58 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1SequenceBatchesEtrog]{
|
| 59 |
+
SupportedEvent: []etherman.EventOrder{etherman.SequenceBatchesOrder, etherman.InitialSequenceBatchesOrder},
|
| 60 |
+
SupportedForkdIds: &actions.ForksIdOnlyEtrog},
|
| 61 |
state: state,
|
| 62 |
sync: sync,
|
| 63 |
timeProvider: timeProvider,
|
|
|
|
| 287 |
|
| 288 |
// Reset trusted state
|
| 289 |
previousBatchNumber := batch.BatchNumber - 1
|
| 290 |
+
if tBatch.StateRoot == (common.Hash{}) {
|
| 291 |
+
log.Warnf("cleaning state before inserting batch from L1. Clean until batch: %d", previousBatchNumber)
|
| 292 |
} else {
|
| 293 |
log.Warnf("missmatch in trusted state detected, discarding batches until batchNum %d", previousBatchNumber)
|
| 294 |
}
|
|
@@ -268,7 +268,7 @@
|
|
| 268 |
TxHash: state.HashByteArray(batch.BatchL2Data),
|
| 269 |
Coinbase: batch.Coinbase,
|
| 270 |
SequencerAddr: common.HexToAddress(addrExampleValues[0]),
|
| 271 |
-
PolygonRollupBaseEtrogBatchData: &
|
| 272 |
Transactions: []byte{},
|
| 273 |
ForcedTimestamp: uint64(forcedTimestamp.Unix()),
|
| 274 |
ForcedGlobalExitRoot: forcedGlobalExitRoot,
|
|
@@ -284,7 +284,7 @@
|
|
| 284 |
TxHash: state.HashByteArray(batch.BatchL2Data),
|
| 285 |
Coinbase: batch.Coinbase,
|
| 286 |
SequencerAddr: common.HexToAddress(addrExampleValues[0]),
|
| 287 |
-
PolygonRollupBaseEtrogBatchData: &
|
| 288 |
Transactions: []byte{},
|
| 289 |
},
|
| 290 |
}
|
|
|
|
| 268 |
TxHash: state.HashByteArray(batch.BatchL2Data),
|
| 269 |
Coinbase: batch.Coinbase,
|
| 270 |
SequencerAddr: common.HexToAddress(addrExampleValues[0]),
|
| 271 |
+
PolygonRollupBaseEtrogBatchData: &polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 272 |
Transactions: []byte{},
|
| 273 |
ForcedTimestamp: uint64(forcedTimestamp.Unix()),
|
| 274 |
ForcedGlobalExitRoot: forcedGlobalExitRoot,
|
|
|
|
| 284 |
TxHash: state.HashByteArray(batch.BatchL2Data),
|
| 285 |
Coinbase: batch.Coinbase,
|
| 286 |
SequencerAddr: common.HexToAddress(addrExampleValues[0]),
|
| 287 |
+
PolygonRollupBaseEtrogBatchData: &polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 288 |
Transactions: []byte{},
|
| 289 |
},
|
| 290 |
}
|
|
@@ -38,9 +38,9 @@
|
|
| 38 |
sync syncProcessUpdateEtrogSequenceInterface,
|
| 39 |
timeProvider syncCommon.TimeProvider) *ProcessorL1UpdateEtrogSequence {
|
| 40 |
return &ProcessorL1UpdateEtrogSequence{
|
| 41 |
-
ProcessorBase:
|
| 42 |
-
[]etherman.EventOrder{etherman.UpdateEtrogSequenceOrder},
|
| 43 |
-
actions.ForksIdOnlyEtrog
|
| 44 |
state: state,
|
| 45 |
sync: sync,
|
| 46 |
timeProvider: timeProvider,
|
|
|
|
| 38 |
sync syncProcessUpdateEtrogSequenceInterface,
|
| 39 |
timeProvider syncCommon.TimeProvider) *ProcessorL1UpdateEtrogSequence {
|
| 40 |
return &ProcessorL1UpdateEtrogSequence{
|
| 41 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1UpdateEtrogSequence]{
|
| 42 |
+
SupportedEvent: []etherman.EventOrder{etherman.UpdateEtrogSequenceOrder},
|
| 43 |
+
SupportedForkdIds: &actions.ForksIdOnlyEtrog},
|
| 44 |
state: state,
|
| 45 |
sync: sync,
|
| 46 |
timeProvider: timeProvider,
|
|
@@ -1,54 +0,0 @@
|
|
| 1 |
-
package feijoa
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
|
| 6 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions"
|
| 10 |
-
"github.com/jackc/pgx/v4"
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
// stateProcessorL1InfoTreeInterface interface required from state
|
| 14 |
-
type stateProcessorL1InfoTreeRecursiveInterface interface {
|
| 15 |
-
AddL1InfoTreeRecursiveLeaf(ctx context.Context, L1InfoTreeLeaf *state.L1InfoTreeLeaf, dbTx pgx.Tx) (*state.L1InfoTreeExitRootStorageEntry, error)
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
// ProcessorL1InfoTreeUpdate implements L1EventProcessor for GlobalExitRootsOrder
|
| 19 |
-
type ProcessorL1InfoTreeUpdate struct {
|
| 20 |
-
actions.ProcessorBase[ProcessorL1InfoTreeUpdate]
|
| 21 |
-
state stateProcessorL1InfoTreeRecursiveInterface
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
// NewProcessorL1InfoTreeUpdate new processor for GlobalExitRootsOrder
|
| 25 |
-
func NewProcessorL1InfoTreeUpdate(state stateProcessorL1InfoTreeRecursiveInterface) *ProcessorL1InfoTreeUpdate {
|
| 26 |
-
return &ProcessorL1InfoTreeUpdate{
|
| 27 |
-
ProcessorBase: *actions.NewProcessorBase[ProcessorL1InfoTreeUpdate](
|
| 28 |
-
[]etherman.EventOrder{etherman.L1InfoTreeOrder},
|
| 29 |
-
actions.ForksIdOnlyFeijoa),
|
| 30 |
-
state: state}
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
// Process process event
|
| 34 |
-
func (p *ProcessorL1InfoTreeUpdate) Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error {
|
| 35 |
-
l1InfoTree := l1Block.L1InfoTree[order.Pos]
|
| 36 |
-
ger := state.GlobalExitRoot{
|
| 37 |
-
BlockNumber: l1InfoTree.BlockNumber,
|
| 38 |
-
MainnetExitRoot: l1InfoTree.MainnetExitRoot,
|
| 39 |
-
RollupExitRoot: l1InfoTree.RollupExitRoot,
|
| 40 |
-
GlobalExitRoot: l1InfoTree.GlobalExitRoot,
|
| 41 |
-
Timestamp: l1InfoTree.Timestamp,
|
| 42 |
-
}
|
| 43 |
-
l1IntoTreeLeaf := state.L1InfoTreeLeaf{
|
| 44 |
-
GlobalExitRoot: ger,
|
| 45 |
-
PreviousBlockHash: l1InfoTree.PreviousBlockHash,
|
| 46 |
-
}
|
| 47 |
-
entry, err := p.state.AddL1InfoTreeRecursiveLeaf(ctx, &l1IntoTreeLeaf, dbTx)
|
| 48 |
-
if err != nil {
|
| 49 |
-
log.Errorf("error storing the l1InfoTree(feijoa). BlockNumber: %d, error: %v", l1Block.BlockNumber, err)
|
| 50 |
-
return err
|
| 51 |
-
}
|
| 52 |
-
log.Infof("L1InfoTree(feijoa) stored. BlockNumber: %d,GER:%s L1InfoTreeIndex: %d L1InfoRoot:%s", l1Block.BlockNumber, entry.GlobalExitRoot.GlobalExitRoot, entry.L1InfoTreeIndex, entry.L1InfoTreeRoot)
|
| 53 |
-
return nil
|
| 54 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,189 +0,0 @@
|
|
| 1 |
-
package feijoa
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
"time"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions"
|
| 12 |
-
commonsync "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 13 |
-
"github.com/ethereum/go-ethereum/common"
|
| 14 |
-
"github.com/jackc/pgx/v4"
|
| 15 |
-
)
|
| 16 |
-
|
| 17 |
-
// stateProcessorSequenceBlobsInterface interface required from state
|
| 18 |
-
type stateProcessorSequenceBlobsInterface interface {
|
| 19 |
-
AddBlobSequence(ctx context.Context, blobSequence *state.BlobSequence, dbTx pgx.Tx) error
|
| 20 |
-
GetLastBlobSequence(ctx context.Context, dbTx pgx.Tx) (*state.BlobSequence, error)
|
| 21 |
-
AddBlobInner(ctx context.Context, blobInner *state.BlobInner, dbTx pgx.Tx) error
|
| 22 |
-
GetL1InfoRecursiveRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
type stateBlobInnerProcessor interface {
|
| 26 |
-
ProcessBlobInner(ctx context.Context, request state.ProcessBlobInnerProcessRequest, data []byte) (*state.ProcessBlobInnerResponse, error)
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
// ProcessorSequenceBlobs processor for SequenceBlobs
|
| 30 |
-
type ProcessorSequenceBlobs struct {
|
| 31 |
-
actions.ProcessorBase[ProcessorL1InfoTreeUpdate]
|
| 32 |
-
state stateProcessorSequenceBlobsInterface
|
| 33 |
-
stateBlobInnerProcessor stateBlobInnerProcessor
|
| 34 |
-
timeProvider commonsync.TimeProvider
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
// NewProcessorSequenceBlobs new processor for SequenceBlobs
|
| 38 |
-
func NewProcessorSequenceBlobs(state stateProcessorSequenceBlobsInterface, stateBlobInnerProcessor stateBlobInnerProcessor, timeProvider commonsync.TimeProvider) *ProcessorSequenceBlobs {
|
| 39 |
-
if timeProvider == nil {
|
| 40 |
-
timeProvider = &commonsync.DefaultTimeProvider{}
|
| 41 |
-
}
|
| 42 |
-
return &ProcessorSequenceBlobs{
|
| 43 |
-
ProcessorBase: *actions.NewProcessorBase[ProcessorL1InfoTreeUpdate](
|
| 44 |
-
[]etherman.EventOrder{etherman.SequenceBlobsOrder},
|
| 45 |
-
actions.ForksIdOnlyFeijoa),
|
| 46 |
-
state: state,
|
| 47 |
-
stateBlobInnerProcessor: stateBlobInnerProcessor,
|
| 48 |
-
timeProvider: timeProvider,
|
| 49 |
-
}
|
| 50 |
-
}
|
| 51 |
-
|
| 52 |
-
// Process process event
|
| 53 |
-
// - Store BlobSequence
|
| 54 |
-
// - Split BlobInner into Batches (executor)
|
| 55 |
-
// - Store BlobInner
|
| 56 |
-
func (p *ProcessorSequenceBlobs) Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error {
|
| 57 |
-
seqBlobs := &l1Block.SequenceBlobs[order.Pos]
|
| 58 |
-
previousBlobSequence, newBlobSequence, err := p.doBlobSequence(ctx, seqBlobs, l1Block, dbTx)
|
| 59 |
-
if err != nil {
|
| 60 |
-
return err
|
| 61 |
-
}
|
| 62 |
-
|
| 63 |
-
for idx := range seqBlobs.Blobs {
|
| 64 |
-
blobNum := newBlobSequence.FirstBlobSequenced + uint64(idx)
|
| 65 |
-
log.Infof("Blob %d: blobNum:%d", idx, blobNum)
|
| 66 |
-
err := p.doBlobInner(ctx, blobNum, &seqBlobs.Blobs[idx], newBlobSequence, previousBlobSequence, dbTx)
|
| 67 |
-
if err != nil {
|
| 68 |
-
return err
|
| 69 |
-
}
|
| 70 |
-
}
|
| 71 |
-
return nil
|
| 72 |
-
}
|
| 73 |
-
func (p *ProcessorSequenceBlobs) doBlobInner(ctx context.Context, blobNum uint64, blob *etherman.SequenceBlob, newBlobSequence, previousBlobSequence *state.BlobSequence, dbTx pgx.Tx) error {
|
| 74 |
-
// TODO: We have to choose which tree depending on ForkID?
|
| 75 |
-
leaf, err := p.state.GetL1InfoRecursiveRootLeafByIndex(ctx, blob.Params.L1InfoLeafIndex, dbTx)
|
| 76 |
-
if err != nil {
|
| 77 |
-
return err
|
| 78 |
-
}
|
| 79 |
-
|
| 80 |
-
stateBlob, err := p.convertToStateBlobInner(blob, blobNum, newBlobSequence.BlobSequenceIndex, leaf.L1InfoTreeRoot)
|
| 81 |
-
if err != nil {
|
| 82 |
-
log.Errorf("Error converting blob to state: %v", err)
|
| 83 |
-
return err
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
processRequest, err := state.NewProcessBlobInnerProcessRequest(uint64(actions.ForkIDFeijoa), stateBlob, previousBlobSequence, *newBlobSequence)
|
| 87 |
-
if err != nil {
|
| 88 |
-
return err
|
| 89 |
-
}
|
| 90 |
-
log.Infof("storing Blob %d: BlobInner: %v", blobNum, stateBlob)
|
| 91 |
-
err = p.state.AddBlobInner(ctx, stateBlob, dbTx)
|
| 92 |
-
if err != nil {
|
| 93 |
-
log.Errorf("Error storing blobInner to state: %v", err)
|
| 94 |
-
return err
|
| 95 |
-
}
|
| 96 |
-
response, err := p.stateBlobInnerProcessor.ProcessBlobInner(ctx, *processRequest, blob.Data)
|
| 97 |
-
if err != nil {
|
| 98 |
-
return err
|
| 99 |
-
}
|
| 100 |
-
if response == nil {
|
| 101 |
-
return errors.New("response is nil")
|
| 102 |
-
}
|
| 103 |
-
log.Infof("Blob %d: response: %v", blobNum, response)
|
| 104 |
-
if response.IsSuccessfulExecution() {
|
| 105 |
-
// We need to store the batches
|
| 106 |
-
outcomeData := response.GetSuccesfulData()
|
| 107 |
-
for idx := 0; idx < outcomeData.HowManyBatches(); idx++ {
|
| 108 |
-
log.Infof("storing Blob %d: Batch %d: Hash:%s", blobNum, idx, outcomeData.GetBatchHash(idx).String())
|
| 109 |
-
// TODO: Store batch
|
| 110 |
-
}
|
| 111 |
-
} else {
|
| 112 |
-
err := response.GetUnifiedError()
|
| 113 |
-
log.Errorf("Blob %d: response is not successful: Err: %s", blobNum, err.Error())
|
| 114 |
-
return err
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
return nil
|
| 118 |
-
}
|
| 119 |
-
|
| 120 |
-
// returns previousBlobSequence and new one
|
| 121 |
-
func (p *ProcessorSequenceBlobs) doBlobSequence(ctx context.Context,
|
| 122 |
-
incommingSequenceBlobs *etherman.SequenceBlobs, l1Block *etherman.Block, dbTx pgx.Tx) (*state.BlobSequence, *state.BlobSequence, error) {
|
| 123 |
-
previousBlobSequence, err := p.state.GetLastBlobSequence(ctx, dbTx)
|
| 124 |
-
if err != nil {
|
| 125 |
-
return nil, nil, err
|
| 126 |
-
}
|
| 127 |
-
blobSequenceIndex := p.calculateBlobSequenceIndex(previousBlobSequence)
|
| 128 |
-
newBlobSequence := p.convertToStateBlobSequence(incommingSequenceBlobs, blobSequenceIndex, l1Block.ReceivedAt, p.timeProvider.Now(), l1Block.BlockNumber)
|
| 129 |
-
log.Infof("storing BlobSequence: %v", newBlobSequence)
|
| 130 |
-
err = p.state.AddBlobSequence(ctx, newBlobSequence, dbTx)
|
| 131 |
-
if err != nil {
|
| 132 |
-
return nil, nil, err
|
| 133 |
-
}
|
| 134 |
-
return previousBlobSequence, newBlobSequence, nil
|
| 135 |
-
}
|
| 136 |
-
|
| 137 |
-
func (p *ProcessorSequenceBlobs) calculateBlobSequenceIndex(previousBlobSequence *state.BlobSequence) uint64 {
|
| 138 |
-
nextIndex := uint64(1)
|
| 139 |
-
if previousBlobSequence != nil {
|
| 140 |
-
nextIndex = previousBlobSequence.BlobSequenceIndex + 1
|
| 141 |
-
}
|
| 142 |
-
return nextIndex
|
| 143 |
-
}
|
| 144 |
-
|
| 145 |
-
func (p *ProcessorSequenceBlobs) convertToStateBlobInner(blobInner *etherman.SequenceBlob, blobInnerNum uint64, blobSequenceIndex uint64, l1InfoTreeRoot common.Hash) (*state.BlobInner, error) {
|
| 146 |
-
res := &state.BlobInner{
|
| 147 |
-
BlobSequenceIndex: blobSequenceIndex,
|
| 148 |
-
BlobInnerNum: blobInnerNum, // ho trect del previousBlobSequence
|
| 149 |
-
Type: p.convertBlobType(blobInner.Type),
|
| 150 |
-
MaxSequenceTimestamp: time.Unix(int64(blobInner.Params.MaxSequenceTimestamp), 0),
|
| 151 |
-
ZkGasLimit: blobInner.Params.ZkGasLimit,
|
| 152 |
-
L1InfoLeafIndex: blobInner.Params.L1InfoLeafIndex,
|
| 153 |
-
L1InfoTreeRoot: l1InfoTreeRoot,
|
| 154 |
-
}
|
| 155 |
-
if res.Type == state.TypeBlobTransaction {
|
| 156 |
-
if blobInner.BlobBlobTypeParams == nil {
|
| 157 |
-
return nil, errors.New("BlobBlobTypeParams from etherman is required for BlobTransaction")
|
| 158 |
-
}
|
| 159 |
-
res.BlobBlobTypeParams = &state.BlobBlobTypeParams{
|
| 160 |
-
BlobIndex: blobInner.BlobBlobTypeParams.BlobIndex.Uint64(),
|
| 161 |
-
Z: blobInner.BlobBlobTypeParams.Z,
|
| 162 |
-
Y: blobInner.BlobBlobTypeParams.Y,
|
| 163 |
-
Commitment: blobInner.BlobBlobTypeParams.Commitment,
|
| 164 |
-
Proof: blobInner.BlobBlobTypeParams.Proof,
|
| 165 |
-
}
|
| 166 |
-
}
|
| 167 |
-
return res, nil
|
| 168 |
-
}
|
| 169 |
-
|
| 170 |
-
func (p *ProcessorSequenceBlobs) convertBlobType(value etherman.BlobType) state.BlobType {
|
| 171 |
-
return state.BlobType(value)
|
| 172 |
-
}
|
| 173 |
-
|
| 174 |
-
func (p *ProcessorSequenceBlobs) convertToStateBlobSequence(etherSeqBlobs *etherman.SequenceBlobs,
|
| 175 |
-
nextIndex uint64,
|
| 176 |
-
createAt time.Time,
|
| 177 |
-
receviedAt time.Time,
|
| 178 |
-
l1BlockNumber uint64) *state.BlobSequence {
|
| 179 |
-
return &state.BlobSequence{
|
| 180 |
-
BlobSequenceIndex: nextIndex,
|
| 181 |
-
L2Coinbase: etherSeqBlobs.L2Coinbase,
|
| 182 |
-
FirstBlobSequenced: etherSeqBlobs.EventData.LastBlobSequenced - uint64(len(etherSeqBlobs.Blobs)),
|
| 183 |
-
LastBlobSequenced: etherSeqBlobs.EventData.LastBlobSequenced,
|
| 184 |
-
FinalAccInputHash: etherSeqBlobs.FinalAccInputHash,
|
| 185 |
-
CreateAt: createAt,
|
| 186 |
-
ReceivedAt: receviedAt,
|
| 187 |
-
BlockNumber: l1BlockNumber,
|
| 188 |
-
}
|
| 189 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,102 +0,0 @@
|
|
| 1 |
-
package feijoa_test
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"os"
|
| 6 |
-
"testing"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/db"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 12 |
-
"github.com/0xPolygonHermez/zkevm-node/state/pgstatestorage"
|
| 13 |
-
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 14 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/feijoa"
|
| 15 |
-
"github.com/0xPolygonHermez/zkevm-node/test/dbutils"
|
| 16 |
-
"github.com/ethereum/go-ethereum/common"
|
| 17 |
-
"github.com/jackc/pgconn"
|
| 18 |
-
"github.com/jackc/pgx/v4"
|
| 19 |
-
"github.com/stretchr/testify/require"
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
// This test is a exploratory test used to develop. It use a sequencedBlob on Sepolia
|
| 23 |
-
// It need Database, a prover >7.x and L1 client
|
| 24 |
-
// TODO: Remove this test or convert to a test than can be executed
|
| 25 |
-
func TestProcessASequenceBlobUsingCallDataFromSepolia(t *testing.T) {
|
| 26 |
-
l1url := os.Getenv("ZKEVM_NODE_ETHERMAN_URL")
|
| 27 |
-
consensusl1url := os.Getenv("ZKEVM_NODE_ETHERMAN_CONSENSUSL1URL")
|
| 28 |
-
if l1url == "" || consensusl1url == "" {
|
| 29 |
-
// You can set un vscode editing setings.json
|
| 30 |
-
// "go.testEnvVars": {
|
| 31 |
-
// "ZKEVM_NODE_ETHERMAN_URL": "url1",
|
| 32 |
-
// "ZKEVM_NODE_ETHERMAN_CONSENSUSL1URL": "url2",
|
| 33 |
-
//}
|
| 34 |
-
t.Skip("ZKEVM_NODE_ETHERMAN_URL or ZKEVM_NODE_ETHERMAN_CONSENSUSL1URL not set")
|
| 35 |
-
}
|
| 36 |
-
cfg := etherman.Config{
|
| 37 |
-
URL: l1url,
|
| 38 |
-
ConsensusL1URL: consensusl1url,
|
| 39 |
-
}
|
| 40 |
-
l1Config := etherman.L1Config{
|
| 41 |
-
L1ChainID: 11155111,
|
| 42 |
-
//ZkEVMAddr: common.HexToAddress("0x31A6ae85297DD0EeBD66D7556941c33Bd41d565C"),
|
| 43 |
-
//ZkEVMAddr: common.HexToAddress("0xD23C761025306cF5038D74FEEb077Cf66DE134DA"),
|
| 44 |
-
ZkEVMAddr: common.HexToAddress("0x5e5880098741d1fbd38eaaac51c4215f80f92d27"),
|
| 45 |
-
RollupManagerAddr: common.HexToAddress("0x9fB0B4A5d4d60aaCfa8DC20B8DF5528Ab26848d3"),
|
| 46 |
-
GlobalExitRootManagerAddr: common.HexToAddress("0x76216E45Bdd20022eEcC07999e50228d7829534B"),
|
| 47 |
-
}
|
| 48 |
-
eth, err := etherman.NewClient(cfg, l1Config)
|
| 49 |
-
require.NoError(t, err)
|
| 50 |
-
ctx := context.Background()
|
| 51 |
-
//toBlock := uint64(5611933)
|
| 52 |
-
//toBlock := uint64(5704000)
|
| 53 |
-
toBlock := uint64(5760696)
|
| 54 |
-
blocks, orders, err := eth.GetRollupInfoByBlockRange(ctx, toBlock, &toBlock)
|
| 55 |
-
require.NoError(t, err)
|
| 56 |
-
require.Equal(t, 1, len(blocks))
|
| 57 |
-
require.Equal(t, 1, len(orders))
|
| 58 |
-
|
| 59 |
-
realState := createRealState(t)
|
| 60 |
-
err = addBlock(ctx, &blocks[0], realState, nil)
|
| 61 |
-
if err != nil {
|
| 62 |
-
log.Error(err)
|
| 63 |
-
}
|
| 64 |
-
sut := feijoa.NewProcessorSequenceBlobs(realState, realState, nil)
|
| 65 |
-
err = sut.Process(ctx, orders[blocks[0].BlockHash][0], &blocks[0], nil)
|
| 66 |
-
require.NoError(t, err)
|
| 67 |
-
}
|
| 68 |
-
|
| 69 |
-
const UniqueViolationErr = "23505"
|
| 70 |
-
|
| 71 |
-
func addBlock(ctx context.Context, block *etherman.Block, storage *state.State, dbTx pgx.Tx) error {
|
| 72 |
-
b := state.Block{
|
| 73 |
-
BlockNumber: block.BlockNumber,
|
| 74 |
-
BlockHash: block.BlockHash,
|
| 75 |
-
ParentHash: block.ParentHash,
|
| 76 |
-
ReceivedAt: block.ReceivedAt,
|
| 77 |
-
}
|
| 78 |
-
// Add block information
|
| 79 |
-
err := storage.AddBlock(ctx, &b, dbTx)
|
| 80 |
-
|
| 81 |
-
if pgerr, ok := err.(*pgconn.PgError); ok && pgerr.Code == UniqueViolationErr {
|
| 82 |
-
return nil
|
| 83 |
-
}
|
| 84 |
-
return err
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
func createRealState(t *testing.T) *state.State {
|
| 88 |
-
stateDBCfg := dbutils.NewStateConfigFromEnv()
|
| 89 |
-
stateCfg := state.Config{}
|
| 90 |
-
err := db.RunMigrationsUp(stateDBCfg, db.StateMigrationName)
|
| 91 |
-
require.NoError(t, err)
|
| 92 |
-
stateSqlDB, err := db.NewSQLDB(stateDBCfg)
|
| 93 |
-
stateDb := pgstatestorage.NewPostgresStorage(stateCfg, stateSqlDB)
|
| 94 |
-
executorConfig := executor.Config{
|
| 95 |
-
URI: "localhost:50071",
|
| 96 |
-
MaxGRPCMessageSize: 1024 * 1024 * 1024,
|
| 97 |
-
}
|
| 98 |
-
executorClient, _, _ := executor.NewExecutorClient(context.TODO(), executorConfig)
|
| 99 |
-
require.NoError(t, err)
|
| 100 |
-
|
| 101 |
-
return state.NewState(stateCfg, stateDb, executorClient, nil, nil, nil, nil)
|
| 102 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -12,41 +12,21 @@
|
|
| 12 |
ForkIDEtrog = ForkIdType(7) //nolint:gomnd
|
| 13 |
// ForkIDElderberry is the forkId for Elderberry
|
| 14 |
ForkIDElderberry = ForkIdType(8) //nolint:gomnd
|
| 15 |
-
//
|
| 16 |
-
|
| 17 |
-
// ForkIDFeijoa is the forkId for Feijoa
|
| 18 |
-
ForkIDFeijoa = ForkIdType(10) //nolint:gomnd
|
| 19 |
)
|
| 20 |
|
| 21 |
var (
|
| 22 |
|
| 23 |
-
/// ************** ALL ***************///
|
| 24 |
-
|
| 25 |
// ForksIdAll support all forkIds
|
| 26 |
ForksIdAll = []ForkIdType{WildcardForkId}
|
| 27 |
|
| 28 |
-
/// ************** SINGLE ***************///
|
| 29 |
-
|
| 30 |
-
// ForksIdOnlyFeijoa support only etrog forkId
|
| 31 |
-
ForksIdOnlyFeijoa = []ForkIdType{ForkIDFeijoa}
|
| 32 |
-
|
| 33 |
// ForksIdOnlyElderberry support only elderberry forkId
|
| 34 |
-
ForksIdOnlyElderberry = []ForkIdType{ForkIDElderberry,
|
| 35 |
|
| 36 |
// ForksIdOnlyEtrog support only etrog forkId
|
| 37 |
ForksIdOnlyEtrog = []ForkIdType{ForkIDEtrog}
|
| 38 |
|
| 39 |
-
/// ************** MULTIPLE ***************///
|
| 40 |
-
|
| 41 |
// ForksIdToIncaberry support all forkIds till incaberry
|
| 42 |
ForksIdToIncaberry = []ForkIdType{1, 2, 3, 4, 5, ForkIDIncaberry}
|
| 43 |
-
|
| 44 |
-
// ForksIdToEtrog support all forkIds till etrog
|
| 45 |
-
ForksIdToEtrog = append(ForksIdToIncaberry, ForksIdOnlyEtrog...)
|
| 46 |
-
|
| 47 |
-
// ForksIdToElderberry support all forkIds till elderberry
|
| 48 |
-
ForksIdToElderberry = append(ForksIdToEtrog, ForksIdOnlyElderberry...)
|
| 49 |
-
|
| 50 |
-
// ForksIdToFeijoa support all forkIds till feijoa
|
| 51 |
-
ForksIdToFeijoa = append(ForksIdToElderberry, ForksIdOnlyFeijoa...)
|
| 52 |
)
|
|
|
|
| 12 |
ForkIDEtrog = ForkIdType(7) //nolint:gomnd
|
| 13 |
// ForkIDElderberry is the forkId for Elderberry
|
| 14 |
ForkIDElderberry = ForkIdType(8) //nolint:gomnd
|
| 15 |
+
// ForkID9 is the forkId for 9
|
| 16 |
+
ForkID9 = ForkIdType(9) //nolint:gomnd
|
|
|
|
|
|
|
| 17 |
)
|
| 18 |
|
| 19 |
var (
|
| 20 |
|
|
|
|
|
|
|
| 21 |
// ForksIdAll support all forkIds
|
| 22 |
ForksIdAll = []ForkIdType{WildcardForkId}
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
// ForksIdOnlyElderberry support only elderberry forkId
|
| 25 |
+
ForksIdOnlyElderberry = []ForkIdType{ForkIDElderberry, ForkID9}
|
| 26 |
|
| 27 |
// ForksIdOnlyEtrog support only etrog forkId
|
| 28 |
ForksIdOnlyEtrog = []ForkIdType{ForkIDEtrog}
|
| 29 |
|
|
|
|
|
|
|
| 30 |
// ForksIdToIncaberry support all forkIds till incaberry
|
| 31 |
ForksIdToIncaberry = []ForkIdType{1, 2, 3, 4, 5, ForkIDIncaberry}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
)
|
|
@@ -23,9 +23,9 @@
|
|
| 23 |
// NewProcessL1ForcedBatches returns instance of a processor for ForcedBatchesOrder
|
| 24 |
func NewProcessL1ForcedBatches(state stateProcessL1ForcedBatchesInterface) *ProcessL1ForcedBatches {
|
| 25 |
return &ProcessL1ForcedBatches{
|
| 26 |
-
ProcessorBase:
|
| 27 |
-
[]etherman.EventOrder{etherman.ForcedBatchesOrder},
|
| 28 |
-
actions.ForksIdAll
|
| 29 |
state: state}
|
| 30 |
}
|
| 31 |
|
|
|
|
| 23 |
// NewProcessL1ForcedBatches returns instance of a processor for ForcedBatchesOrder
|
| 24 |
func NewProcessL1ForcedBatches(state stateProcessL1ForcedBatchesInterface) *ProcessL1ForcedBatches {
|
| 25 |
return &ProcessL1ForcedBatches{
|
| 26 |
+
ProcessorBase: actions.ProcessorBase[ProcessL1ForcedBatches]{
|
| 27 |
+
SupportedEvent: []etherman.EventOrder{etherman.ForcedBatchesOrder},
|
| 28 |
+
SupportedForkdIds: &actions.ForksIdAll},
|
| 29 |
state: state}
|
| 30 |
}
|
| 31 |
|
|
@@ -36,9 +36,10 @@
|
|
| 36 |
// NewProcessorForkId returns instance of a processor for ForkIDsOrder
|
| 37 |
func NewProcessorForkId(state stateProcessorForkIdInterface, sync syncProcessorForkIdInterface) *ProcessorForkId {
|
| 38 |
return &ProcessorForkId{
|
| 39 |
-
ProcessorBase:
|
| 40 |
-
[]etherman.EventOrder{etherman.ForkIDsOrder},
|
| 41 |
-
actions.ForksIdAll
|
|
|
|
| 42 |
state: state,
|
| 43 |
sync: sync}
|
| 44 |
}
|
|
|
|
| 36 |
// NewProcessorForkId returns instance of a processor for ForkIDsOrder
|
| 37 |
func NewProcessorForkId(state stateProcessorForkIdInterface, sync syncProcessorForkIdInterface) *ProcessorForkId {
|
| 38 |
return &ProcessorForkId{
|
| 39 |
+
ProcessorBase: actions.ProcessorBase[ProcessorForkId]{
|
| 40 |
+
SupportedEvent: []etherman.EventOrder{etherman.ForkIDsOrder},
|
| 41 |
+
SupportedForkdIds: &actions.ForksIdAll,
|
| 42 |
+
},
|
| 43 |
state: state,
|
| 44 |
sync: sync}
|
| 45 |
}
|
|
@@ -24,9 +24,9 @@
|
|
| 24 |
// NewProcessorL1GlobalExitRoot new processor for GlobalExitRootsOrder
|
| 25 |
func NewProcessorL1GlobalExitRoot(state stateProcessorL1GlobalExitRootInterface) *ProcessorL1GlobalExitRoot {
|
| 26 |
return &ProcessorL1GlobalExitRoot{
|
| 27 |
-
ProcessorBase:
|
| 28 |
-
[]etherman.EventOrder{etherman.GlobalExitRootsOrder},
|
| 29 |
-
actions.ForksIdToIncaberry
|
| 30 |
state: state}
|
| 31 |
}
|
| 32 |
|
|
|
|
| 24 |
// NewProcessorL1GlobalExitRoot new processor for GlobalExitRootsOrder
|
| 25 |
func NewProcessorL1GlobalExitRoot(state stateProcessorL1GlobalExitRootInterface) *ProcessorL1GlobalExitRoot {
|
| 26 |
return &ProcessorL1GlobalExitRoot{
|
| 27 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1GlobalExitRoot]{
|
| 28 |
+
SupportedEvent: []etherman.EventOrder{etherman.GlobalExitRootsOrder},
|
| 29 |
+
SupportedForkdIds: &actions.ForksIdToIncaberry},
|
| 30 |
state: state}
|
| 31 |
}
|
| 32 |
|
|
@@ -64,9 +64,9 @@
|
|
| 64 |
func NewProcessorL1SequenceBatches(state stateProcessSequenceBatches,
|
| 65 |
etherMan ethermanProcessSequenceBatches, pool poolProcessSequenceBatchesInterface, eventLog syncinterfaces.EventLogInterface, sync syncProcessSequenceBatchesInterface) *ProcessorL1SequenceBatches {
|
| 66 |
return &ProcessorL1SequenceBatches{
|
| 67 |
-
ProcessorBase:
|
| 68 |
-
[]etherman.EventOrder{etherman.SequenceBatchesOrder},
|
| 69 |
-
actions.ForksIdToIncaberry
|
| 70 |
state: state,
|
| 71 |
etherMan: etherMan,
|
| 72 |
pool: pool,
|
|
|
|
| 64 |
func NewProcessorL1SequenceBatches(state stateProcessSequenceBatches,
|
| 65 |
etherMan ethermanProcessSequenceBatches, pool poolProcessSequenceBatchesInterface, eventLog syncinterfaces.EventLogInterface, sync syncProcessSequenceBatchesInterface) *ProcessorL1SequenceBatches {
|
| 66 |
return &ProcessorL1SequenceBatches{
|
| 67 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1SequenceBatches]{
|
| 68 |
+
SupportedEvent: []etherman.EventOrder{etherman.SequenceBatchesOrder},
|
| 69 |
+
SupportedForkdIds: &actions.ForksIdToIncaberry},
|
| 70 |
state: state,
|
| 71 |
etherMan: etherMan,
|
| 72 |
pool: pool,
|
|
@@ -23,7 +23,6 @@
|
|
| 23 |
// Create an instance of ProcessorL1SequenceBatches
|
| 24 |
|
| 25 |
// Test invalid call, no sequenced batches
|
| 26 |
-
sut.ProcessorBase.SupportedEvents()
|
| 27 |
err := sut.Process(ctx, etherman.Order{Name: sut.SupportedEvents()[0], Pos: 0}, l1Block, dbTx)
|
| 28 |
require.Error(t, err)
|
| 29 |
}
|
|
|
|
| 23 |
// Create an instance of ProcessorL1SequenceBatches
|
| 24 |
|
| 25 |
// Test invalid call, no sequenced batches
|
|
|
|
| 26 |
err := sut.Process(ctx, etherman.Order{Name: sut.SupportedEvents()[0], Pos: 0}, l1Block, dbTx)
|
| 27 |
require.Error(t, err)
|
| 28 |
}
|
|
@@ -39,9 +39,9 @@
|
|
| 39 |
func NewProcessL1SequenceForcedBatches(state stateProcessL1SequenceForcedBatchesInterface,
|
| 40 |
sync syncProcessL1SequenceForcedBatchesInterface) *ProcessL1SequenceForcedBatches {
|
| 41 |
return &ProcessL1SequenceForcedBatches{
|
| 42 |
-
ProcessorBase:
|
| 43 |
-
[]etherman.EventOrder{etherman.SequenceForceBatchesOrder},
|
| 44 |
-
actions.ForksIdAll
|
| 45 |
state: state,
|
| 46 |
sync: sync}
|
| 47 |
}
|
|
|
|
| 39 |
func NewProcessL1SequenceForcedBatches(state stateProcessL1SequenceForcedBatchesInterface,
|
| 40 |
sync syncProcessL1SequenceForcedBatchesInterface) *ProcessL1SequenceForcedBatches {
|
| 41 |
return &ProcessL1SequenceForcedBatches{
|
| 42 |
+
ProcessorBase: actions.ProcessorBase[ProcessL1SequenceForcedBatches]{
|
| 43 |
+
SupportedEvent: []etherman.EventOrder{etherman.SequenceForceBatchesOrder},
|
| 44 |
+
SupportedForkdIds: &actions.ForksIdAll},
|
| 45 |
state: state,
|
| 46 |
sync: sync}
|
| 47 |
}
|
|
@@ -26,9 +26,9 @@
|
|
| 26 |
// NewProcessorL1VerifyBatch returns instance of a processor for VerifyBatchOrder
|
| 27 |
func NewProcessorL1VerifyBatch(state stateL1VerifyBatchInterface) *ProcessorL1VerifyBatch {
|
| 28 |
return &ProcessorL1VerifyBatch{
|
| 29 |
-
ProcessorBase:
|
| 30 |
-
[]etherman.EventOrder{etherman.VerifyBatchOrder, etherman.TrustedVerifyBatchOrder},
|
| 31 |
-
actions.ForksIdAll
|
| 32 |
state: state,
|
| 33 |
}
|
| 34 |
}
|
|
|
|
| 26 |
// NewProcessorL1VerifyBatch returns instance of a processor for VerifyBatchOrder
|
| 27 |
func NewProcessorL1VerifyBatch(state stateL1VerifyBatchInterface) *ProcessorL1VerifyBatch {
|
| 28 |
return &ProcessorL1VerifyBatch{
|
| 29 |
+
ProcessorBase: actions.ProcessorBase[ProcessorL1VerifyBatch]{
|
| 30 |
+
SupportedEvent: []etherman.EventOrder{etherman.VerifyBatchOrder, etherman.TrustedVerifyBatchOrder},
|
| 31 |
+
SupportedForkdIds: &actions.ForksIdAll},
|
| 32 |
state: state,
|
| 33 |
}
|
| 34 |
}
|
|
@@ -9,18 +9,8 @@
|
|
| 9 |
// ProcessorBase is the base struct for all the processors, if reduces the boilerplate
|
| 10 |
// implementing the Name, SupportedEvents and SupportedForkIds functions
|
| 11 |
type ProcessorBase[T any] struct {
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
}
|
| 15 |
-
|
| 16 |
-
// NewProcessorBase creates and initializes internal fields of an new instance of ProcessorBase
|
| 17 |
-
func NewProcessorBase[T any](supportedEvent []etherman.EventOrder, supportedForkIds []ForkIdType) *ProcessorBase[T] {
|
| 18 |
-
p := &ProcessorBase[T]{
|
| 19 |
-
supportedEvent: supportedEvent,
|
| 20 |
-
supportedForkIds: supportedForkIds,
|
| 21 |
-
}
|
| 22 |
-
|
| 23 |
-
return p
|
| 24 |
}
|
| 25 |
|
| 26 |
// Name returns the name of the struct T
|
|
@@ -33,13 +23,13 @@
|
|
| 33 |
|
| 34 |
// SupportedEvents returns the supported events in the struct
|
| 35 |
func (p *ProcessorBase[T]) SupportedEvents() []etherman.EventOrder {
|
| 36 |
-
return p.
|
| 37 |
}
|
| 38 |
|
| 39 |
-
// SupportedForkIds returns the supported forkIds in the struct or the
|
| 40 |
func (p *ProcessorBase[T]) SupportedForkIds() []ForkIdType {
|
| 41 |
-
if
|
| 42 |
-
return p.
|
| 43 |
}
|
| 44 |
// returns none
|
| 45 |
return []ForkIdType{}
|
|
|
|
| 9 |
// ProcessorBase is the base struct for all the processors, if reduces the boilerplate
|
| 10 |
// implementing the Name, SupportedEvents and SupportedForkIds functions
|
| 11 |
type ProcessorBase[T any] struct {
|
| 12 |
+
SupportedEvent []etherman.EventOrder
|
| 13 |
+
SupportedForkdIds *[]ForkIdType
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
}
|
| 15 |
|
| 16 |
// Name returns the name of the struct T
|
|
|
|
| 23 |
|
| 24 |
// SupportedEvents returns the supported events in the struct
|
| 25 |
func (p *ProcessorBase[T]) SupportedEvents() []etherman.EventOrder {
|
| 26 |
+
return p.SupportedEvent
|
| 27 |
}
|
| 28 |
|
| 29 |
+
// SupportedForkIds returns the supported forkIds in the struct or the dafault till incaberry forkId
|
| 30 |
func (p *ProcessorBase[T]) SupportedForkIds() []ForkIdType {
|
| 31 |
+
if p.SupportedForkdIds != nil {
|
| 32 |
+
return *p.SupportedForkdIds
|
| 33 |
}
|
| 34 |
// returns none
|
| 35 |
return []ForkIdType{}
|
|
@@ -1,21 +0,0 @@
|
|
| 1 |
-
package syncinterfaces
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
|
| 6 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 7 |
-
"github.com/ethereum/go-ethereum/common"
|
| 8 |
-
"github.com/jackc/pgx/v4"
|
| 9 |
-
)
|
| 10 |
-
|
| 11 |
-
type ProcessBlockRangeL1BlocksMode bool
|
| 12 |
-
|
| 13 |
-
const (
|
| 14 |
-
StoreL1Blocks ProcessBlockRangeL1BlocksMode = true
|
| 15 |
-
NoStoreL1Blocks ProcessBlockRangeL1BlocksMode = false
|
| 16 |
-
)
|
| 17 |
-
|
| 18 |
-
type BlockRangeProcessor interface {
|
| 19 |
-
ProcessBlockRange(ctx context.Context, blocks []etherman.Block, order map[common.Hash][]etherman.Order) error
|
| 20 |
-
ProcessBlockRangeSingleDbTx(ctx context.Context, blocks []etherman.Block, order map[common.Hash][]etherman.Order, storeBlocks ProcessBlockRangeL1BlocksMode, dbTx pgx.Tx) error
|
| 21 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -20,14 +20,8 @@
|
|
| 20 |
|
| 21 |
EthermanGetLatestBatchNumber
|
| 22 |
GetFinalizedBlockNumber(ctx context.Context) (uint64, error)
|
| 23 |
-
EthermanPreRollup
|
| 24 |
}
|
| 25 |
|
| 26 |
type EthermanGetLatestBatchNumber interface {
|
| 27 |
GetLatestBatchNumber() (uint64, error)
|
| 28 |
}
|
| 29 |
-
|
| 30 |
-
type EthermanPreRollup interface {
|
| 31 |
-
GetL1BlockUpgradeLxLy(ctx context.Context, genesisBlock uint64) (uint64, error)
|
| 32 |
-
GetRollupInfoByBlockRangePreviousRollupGenesis(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]etherman.Block, map[common.Hash][]etherman.Order, error)
|
| 33 |
-
}
|
|
|
|
| 20 |
|
| 21 |
EthermanGetLatestBatchNumber
|
| 22 |
GetFinalizedBlockNumber(ctx context.Context) (uint64, error)
|
|
|
|
| 23 |
}
|
| 24 |
|
| 25 |
type EthermanGetLatestBatchNumber interface {
|
| 26 |
GetLatestBatchNumber() (uint64, error)
|
| 27 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,14 +0,0 @@
|
|
| 1 |
-
package syncinterfaces
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
|
| 6 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions"
|
| 8 |
-
"github.com/jackc/pgx/v4"
|
| 9 |
-
)
|
| 10 |
-
|
| 11 |
-
type L1EventProcessorManager interface {
|
| 12 |
-
Process(ctx context.Context, forkId actions.ForkIdType, order etherman.Order, block *etherman.Block, dbTx pgx.Tx) error
|
| 13 |
-
Get(forkId actions.ForkIdType, event etherman.EventOrder) actions.L1EventProcessor
|
| 14 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -21,13 +21,6 @@
|
|
| 21 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 22 |
}
|
| 23 |
|
| 24 |
-
type StateLastBlockGetter interface {
|
| 25 |
-
GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*state.Block, error)
|
| 26 |
-
}
|
| 27 |
-
|
| 28 |
-
type StateBlobSequencer interface {
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
// StateFullInterface gathers the methods required to interact with the state.
|
| 32 |
type StateFullInterface interface {
|
| 33 |
GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*state.Block, error)
|
|
@@ -73,7 +66,6 @@
|
|
| 73 |
GetForkIDByBlockNumber(blockNumber uint64) uint64
|
| 74 |
GetStoredFlushID(ctx context.Context) (uint64, string, error)
|
| 75 |
AddL1InfoTreeLeaf(ctx context.Context, L1InfoTreeLeaf *state.L1InfoTreeLeaf, dbTx pgx.Tx) (*state.L1InfoTreeExitRootStorageEntry, error)
|
| 76 |
-
AddL1InfoTreeRecursiveLeaf(ctx context.Context, L1InfoTreeLeaf *state.L1InfoTreeLeaf, dbTx pgx.Tx) (*state.L1InfoTreeExitRootStorageEntry, error)
|
| 77 |
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) error
|
| 78 |
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 79 |
UpdateWIPBatch(ctx context.Context, receipt state.ProcessingReceipt, dbTx pgx.Tx) error
|
|
@@ -84,11 +76,6 @@
|
|
| 84 |
UpdateForkIDBlockNumber(ctx context.Context, forkdID uint64, newBlockNumber uint64, updateMemCache bool, dbTx pgx.Tx) error
|
| 85 |
GetLastL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 86 |
GetL2BlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.L2Block, error)
|
| 87 |
-
GetLastBlobSequence(ctx context.Context, dbTx pgx.Tx) (*state.BlobSequence, error)
|
| 88 |
-
AddBlobSequence(ctx context.Context, blobSequence *state.BlobSequence, dbTx pgx.Tx) error
|
| 89 |
-
GetL1InfoRecursiveRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 90 |
-
ProcessBlobInner(ctx context.Context, request state.ProcessBlobInnerProcessRequest, data []byte) (*state.ProcessBlobInnerResponse, error)
|
| 91 |
-
AddBlobInner(ctx context.Context, blobInner *state.BlobInner, dbTx pgx.Tx) error
|
| 92 |
GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*state.Block, error)
|
| 93 |
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 94 |
}
|
|
|
|
| 21 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 22 |
}
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
// StateFullInterface gathers the methods required to interact with the state.
|
| 25 |
type StateFullInterface interface {
|
| 26 |
GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*state.Block, error)
|
|
|
|
| 66 |
GetForkIDByBlockNumber(blockNumber uint64) uint64
|
| 67 |
GetStoredFlushID(ctx context.Context) (uint64, string, error)
|
| 68 |
AddL1InfoTreeLeaf(ctx context.Context, L1InfoTreeLeaf *state.L1InfoTreeLeaf, dbTx pgx.Tx) (*state.L1InfoTreeExitRootStorageEntry, error)
|
|
|
|
| 69 |
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) error
|
| 70 |
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 71 |
UpdateWIPBatch(ctx context.Context, receipt state.ProcessingReceipt, dbTx pgx.Tx) error
|
|
|
|
| 76 |
UpdateForkIDBlockNumber(ctx context.Context, forkdID uint64, newBlockNumber uint64, updateMemCache bool, dbTx pgx.Tx) error
|
| 77 |
GetLastL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 78 |
GetL2BlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.L2Block, error)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*state.Block, error)
|
| 80 |
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 81 |
}
|
|
@@ -1,10 +0,0 @@
|
|
| 1 |
-
package syncinterfaces
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
)
|
| 6 |
-
|
| 7 |
-
// SyncPreRollupSyncer is the interface for synchronizing pre genesis rollup events
|
| 8 |
-
type SyncPreRollupSyncer interface {
|
| 9 |
-
SynchronizePreGenesisRollupEvents(ctx context.Context) error
|
| 10 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -20,9 +20,9 @@
|
|
| 20 |
|
| 21 |
// L1SyncCheckL2BlockHash if is true when a batch is closed is force to check L2Block hash against trustedNode (only apply for permissionless)
|
| 22 |
L1SyncCheckL2BlockHash bool `mapstructure:"L1SyncCheckL2BlockHash"`
|
| 23 |
-
//
|
| 24 |
// a modules 5, for instance, means check all l2block multiples of 5 (10,15,20,...)
|
| 25 |
-
|
| 26 |
|
| 27 |
L1BlockCheck L1BlockCheckConfig `mapstructure:"L1BlockCheck"`
|
| 28 |
// L1SynchronizationMode define how to synchronize with L1:
|
|
|
|
| 20 |
|
| 21 |
// L1SyncCheckL2BlockHash if is true when a batch is closed is force to check L2Block hash against trustedNode (only apply for permissionless)
|
| 22 |
L1SyncCheckL2BlockHash bool `mapstructure:"L1SyncCheckL2BlockHash"`
|
| 23 |
+
// L1SyncCheckL2BlockNumberhModulus is the modulus used to choose the l2block to check
|
| 24 |
// a modules 5, for instance, means check all l2block multiples of 5 (10,15,20,...)
|
| 25 |
+
L1SyncCheckL2BlockNumberhModulus uint64 `mapstructure:"L1SyncCheckL2BlockNumberhModulus"`
|
| 26 |
|
| 27 |
L1BlockCheck L1BlockCheckConfig `mapstructure:"L1BlockCheck"`
|
| 28 |
// L1SynchronizationMode define how to synchronize with L1:
|
|
@@ -18,7 +17,6 @@
|
|
| 18 |
p.Register(actions.NewCheckL2BlockDecorator(incaberry.NewProcessL1SequenceForcedBatches(sync.state, sync), l2Blockchecker))
|
| 19 |
p.Register(incaberry.NewProcessorForkId(sync.state, sync))
|
| 20 |
p.Register(etrog.NewProcessorL1InfoTreeUpdate(sync.state))
|
| 21 |
-
p.Register(feijoa.NewProcessorL1InfoTreeUpdate(sync.state))
|
| 22 |
sequenceBatchesProcessor := etrog.NewProcessorL1SequenceBatches(sync.state, sync, common.DefaultTimeProvider{}, sync.halter)
|
| 23 |
p.Register(actions.NewCheckL2BlockDecorator(sequenceBatchesProcessor, l2Blockchecker))
|
| 24 |
p.Register(incaberry.NewProcessorL1VerifyBatch(sync.state))
|
|
@@ -26,6 +24,5 @@
|
|
| 26 |
p.Register(actions.NewCheckL2BlockDecorator(elderberry.NewProcessorL1SequenceBatchesElderberry(sequenceBatchesProcessor, sync.state), l2Blockchecker))
|
| 27 |
// intialSequence is process in ETROG by the same class, this is just a wrapper to pass directly to ETROG
|
| 28 |
p.Register(elderberry.NewProcessorL1InitialSequenceBatchesElderberry(sequenceBatchesProcessor))
|
| 29 |
-
p.Register(feijoa.NewProcessorSequenceBlobs(sync.state, sync.state, nil))
|
| 30 |
return p.Build()
|
| 31 |
}
|
|
|
|
| 17 |
p.Register(actions.NewCheckL2BlockDecorator(incaberry.NewProcessL1SequenceForcedBatches(sync.state, sync), l2Blockchecker))
|
| 18 |
p.Register(incaberry.NewProcessorForkId(sync.state, sync))
|
| 19 |
p.Register(etrog.NewProcessorL1InfoTreeUpdate(sync.state))
|
|
|
|
| 20 |
sequenceBatchesProcessor := etrog.NewProcessorL1SequenceBatches(sync.state, sync, common.DefaultTimeProvider{}, sync.halter)
|
| 21 |
p.Register(actions.NewCheckL2BlockDecorator(sequenceBatchesProcessor, l2Blockchecker))
|
| 22 |
p.Register(incaberry.NewProcessorL1VerifyBatch(sync.state))
|
|
|
|
| 24 |
p.Register(actions.NewCheckL2BlockDecorator(elderberry.NewProcessorL1SequenceBatchesElderberry(sequenceBatchesProcessor, sync.state), l2Blockchecker))
|
| 25 |
// intialSequence is process in ETROG by the same class, this is just a wrapper to pass directly to ETROG
|
| 26 |
p.Register(elderberry.NewProcessorL1InitialSequenceBatchesElderberry(sequenceBatchesProcessor))
|
|
|
|
| 27 |
return p.Build()
|
| 28 |
}
|
|
@@ -11,7 +11,7 @@
|
|
| 11 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 12 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 13 |
syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 14 |
-
"github.com/
|
| 15 |
types "github.com/ethereum/go-ethereum/core/types"
|
| 16 |
)
|
| 17 |
|
|
@@ -33,10 +33,16 @@
|
|
| 33 |
AceptableInacctivityTime time.Duration
|
| 34 |
}
|
| 35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
// l1RollupInfoConsumer is the object that process the rollup info data incomming from channel chIncommingRollupInfo
|
| 37 |
type l1RollupInfoConsumer struct {
|
| 38 |
mutex sync.Mutex
|
| 39 |
-
synchronizer
|
| 40 |
chIncommingRollupInfo chan L1SyncMessage
|
| 41 |
ctx context.Context
|
| 42 |
statistics l1RollupInfoConsumerStatistics
|
|
@@ -47,7 +53,7 @@
|
|
| 47 |
|
| 48 |
// NewL1RollupInfoConsumer creates a new l1RollupInfoConsumer
|
| 49 |
func NewL1RollupInfoConsumer(cfg ConfigConsumer,
|
| 50 |
-
synchronizer
|
| 51 |
if cfg.AceptableInacctivityTime < minAcceptableTimeWaitingForNewRollupInfoData {
|
| 52 |
log.Warnf("consumer: the AceptableInacctivityTime is too low (%s) minimum recommended %s", cfg.AceptableInacctivityTime, minAcceptableTimeWaitingForNewRollupInfoData)
|
| 53 |
}
|
|
@@ -231,7 +237,7 @@
|
|
| 231 |
return nil, nil
|
| 232 |
}
|
| 233 |
b := convertL1BlockToEthBlock(lb)
|
| 234 |
-
err := l.synchronizer.ProcessBlockRange(
|
| 235 |
if err != nil {
|
| 236 |
log.Error("consumer: Error processing last block of range: ", rollupInfo.blockRange, " err:", err)
|
| 237 |
return nil, err
|
|
@@ -243,7 +249,7 @@
|
|
| 243 |
tmpStateBlock := convertEthmanBlockToStateBlock(&blocks[len(blocks)-1])
|
| 244 |
lastEthBlockSynced = &tmpStateBlock
|
| 245 |
logBlocks(blocks)
|
| 246 |
-
err := l.synchronizer.ProcessBlockRange(
|
| 247 |
if err != nil {
|
| 248 |
log.Info("consumer: Error processing block range: ", rollupInfo.blockRange, " err:", err)
|
| 249 |
return nil, err
|
|
|
|
| 11 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 12 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 13 |
syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 14 |
+
"github.com/ethereum/go-ethereum/common"
|
| 15 |
types "github.com/ethereum/go-ethereum/core/types"
|
| 16 |
)
|
| 17 |
|
|
|
|
| 33 |
AceptableInacctivityTime time.Duration
|
| 34 |
}
|
| 35 |
|
| 36 |
+
// synchronizerProcessBlockRangeInterface is the interface with synchronizer
|
| 37 |
+
// to execute blocks. This interface is used to mock the synchronizer in the tests
|
| 38 |
+
type synchronizerProcessBlockRangeInterface interface {
|
| 39 |
+
ProcessBlockRange(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
// l1RollupInfoConsumer is the object that process the rollup info data incomming from channel chIncommingRollupInfo
|
| 43 |
type l1RollupInfoConsumer struct {
|
| 44 |
mutex sync.Mutex
|
| 45 |
+
synchronizer synchronizerProcessBlockRangeInterface
|
| 46 |
chIncommingRollupInfo chan L1SyncMessage
|
| 47 |
ctx context.Context
|
| 48 |
statistics l1RollupInfoConsumerStatistics
|
|
|
|
| 53 |
|
| 54 |
// NewL1RollupInfoConsumer creates a new l1RollupInfoConsumer
|
| 55 |
func NewL1RollupInfoConsumer(cfg ConfigConsumer,
|
| 56 |
+
synchronizer synchronizerProcessBlockRangeInterface, ch chan L1SyncMessage) *l1RollupInfoConsumer {
|
| 57 |
if cfg.AceptableInacctivityTime < minAcceptableTimeWaitingForNewRollupInfoData {
|
| 58 |
log.Warnf("consumer: the AceptableInacctivityTime is too low (%s) minimum recommended %s", cfg.AceptableInacctivityTime, minAcceptableTimeWaitingForNewRollupInfoData)
|
| 59 |
}
|
|
|
|
| 237 |
return nil, nil
|
| 238 |
}
|
| 239 |
b := convertL1BlockToEthBlock(lb)
|
| 240 |
+
err := l.synchronizer.ProcessBlockRange([]etherman.Block{b}, order)
|
| 241 |
if err != nil {
|
| 242 |
log.Error("consumer: Error processing last block of range: ", rollupInfo.blockRange, " err:", err)
|
| 243 |
return nil, err
|
|
|
|
| 249 |
tmpStateBlock := convertEthmanBlockToStateBlock(&blocks[len(blocks)-1])
|
| 250 |
lastEthBlockSynced = &tmpStateBlock
|
| 251 |
logBlocks(blocks)
|
| 252 |
+
err := l.synchronizer.ProcessBlockRange(blocks, order)
|
| 253 |
if err != nil {
|
| 254 |
log.Info("consumer: Error processing block range: ", rollupInfo.blockRange, " err:", err)
|
| 255 |
return nil, err
|
|
@@ -17,7 +16,7 @@
|
|
| 17 |
|
| 18 |
type consumerTestData struct {
|
| 19 |
sut *l1RollupInfoConsumer
|
| 20 |
-
syncMock *
|
| 21 |
ch chan L1SyncMessage
|
| 22 |
}
|
| 23 |
|
|
@@ -55,7 +54,7 @@
|
|
| 55 |
lastBlockOfRange: types.NewBlock(&types.Header{Number: big.NewInt(123)}, nil, nil, nil, nil),
|
| 56 |
}
|
| 57 |
data.syncMock.
|
| 58 |
-
On("ProcessBlockRange", mock.Anything, mock.Anything
|
| 59 |
Return(errors.New("error")).
|
| 60 |
Once()
|
| 61 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
|
@@ -107,7 +106,7 @@
|
|
| 107 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 108 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(200)
|
| 109 |
data.syncMock.
|
| 110 |
-
On("ProcessBlockRange", mock.Anything, mock.Anything
|
| 111 |
Return(nil).
|
| 112 |
Once()
|
| 113 |
err := data.sut.Start(ctxTimeout, nil)
|
|
@@ -134,7 +133,7 @@
|
|
| 134 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 135 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(300)
|
| 136 |
data.syncMock.
|
| 137 |
-
On("ProcessBlockRange", mock.Anything, mock.Anything
|
| 138 |
Return(nil).
|
| 139 |
Once()
|
| 140 |
err := data.sut.Start(ctxTimeout, nil)
|
|
@@ -163,7 +162,7 @@
|
|
| 163 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 164 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(200)
|
| 165 |
data.syncMock.
|
| 166 |
-
On("ProcessBlockRange", mock.Anything, mock.Anything
|
| 167 |
Return(nil).
|
| 168 |
Once()
|
| 169 |
err := data.sut.Start(ctxTimeout, nil)
|
|
@@ -192,7 +191,7 @@
|
|
| 192 |
responseRollupInfoByBlockRange.blockRange.toBlock = 400
|
| 193 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 194 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(200)
|
| 195 |
-
data.syncMock.EXPECT().ProcessBlockRange(mock.Anything, mock.Anything
|
| 196 |
err := data.sut.Start(ctxTimeout, nil)
|
| 197 |
require.NoError(t, err)
|
| 198 |
}
|
|
@@ -207,7 +206,7 @@
|
|
| 207 |
}
|
| 208 |
|
| 209 |
func setupConsumerTest(t *testing.T) consumerTestData {
|
| 210 |
-
syncMock :=
|
| 211 |
ch := make(chan L1SyncMessage, 10)
|
| 212 |
|
| 213 |
cfg := ConfigConsumer{
|
|
|
|
| 16 |
|
| 17 |
type consumerTestData struct {
|
| 18 |
sut *l1RollupInfoConsumer
|
| 19 |
+
syncMock *synchronizerProcessBlockRangeInterfaceMock
|
| 20 |
ch chan L1SyncMessage
|
| 21 |
}
|
| 22 |
|
|
|
|
| 54 |
lastBlockOfRange: types.NewBlock(&types.Header{Number: big.NewInt(123)}, nil, nil, nil, nil),
|
| 55 |
}
|
| 56 |
data.syncMock.
|
| 57 |
+
On("ProcessBlockRange", mock.Anything, mock.Anything).
|
| 58 |
Return(errors.New("error")).
|
| 59 |
Once()
|
| 60 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
|
|
|
| 106 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 107 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(200)
|
| 108 |
data.syncMock.
|
| 109 |
+
On("ProcessBlockRange", mock.Anything, mock.Anything).
|
| 110 |
Return(nil).
|
| 111 |
Once()
|
| 112 |
err := data.sut.Start(ctxTimeout, nil)
|
|
|
|
| 133 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 134 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(300)
|
| 135 |
data.syncMock.
|
| 136 |
+
On("ProcessBlockRange", mock.Anything, mock.Anything).
|
| 137 |
Return(nil).
|
| 138 |
Once()
|
| 139 |
err := data.sut.Start(ctxTimeout, nil)
|
|
|
|
| 162 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 163 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(200)
|
| 164 |
data.syncMock.
|
| 165 |
+
On("ProcessBlockRange", mock.Anything, mock.Anything).
|
| 166 |
Return(nil).
|
| 167 |
Once()
|
| 168 |
err := data.sut.Start(ctxTimeout, nil)
|
|
|
|
| 191 |
responseRollupInfoByBlockRange.blockRange.toBlock = 400
|
| 192 |
data.ch <- *newL1SyncMessageData(&responseRollupInfoByBlockRange)
|
| 193 |
data.ch <- *newL1SyncMessageControlWProducerIsFullySynced(200)
|
| 194 |
+
data.syncMock.EXPECT().ProcessBlockRange(mock.Anything, mock.Anything).Return(nil).Times(1)
|
| 195 |
err := data.sut.Start(ctxTimeout, nil)
|
| 196 |
require.NoError(t, err)
|
| 197 |
}
|
|
|
|
| 206 |
}
|
| 207 |
|
| 208 |
func setupConsumerTest(t *testing.T) consumerTestData {
|
| 209 |
+
syncMock := newSynchronizerProcessBlockRangeInterfaceMock(t)
|
| 210 |
ch := make(chan L1SyncMessage, 10)
|
| 211 |
|
| 212 |
cfg := ConfigConsumer{
|
|
@@ -31,7 +31,7 @@
|
|
| 31 |
GlobalExitRootManagerAddr: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"),
|
| 32 |
}
|
| 33 |
|
| 34 |
-
ethermanClient, err := etherman.NewClient(cfg, l1Config)
|
| 35 |
require.NoError(t, err)
|
| 36 |
worker := newWorker(ethermanClient)
|
| 37 |
ch := make(chan responseRollupInfoByBlockRange)
|
|
|
|
| 31 |
GlobalExitRootManagerAddr: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"),
|
| 32 |
}
|
| 33 |
|
| 34 |
+
ethermanClient, err := etherman.NewClient(cfg, l1Config, nil, nil)
|
| 35 |
require.NoError(t, err)
|
| 36 |
worker := newWorker(ethermanClient)
|
| 37 |
ch := make(chan responseRollupInfoByBlockRange)
|
|
@@ -429,6 +430,7 @@
|
|
| 429 |
Transactions: data.TrustedBatch.BatchL2Data,
|
| 430 |
ForkID: b.state.GetForkIDByBatchNumber(uint64(data.TrustedBatch.Number)),
|
| 431 |
SkipVerifyL1InfoRoot_V2: true,
|
|
|
|
| 432 |
}
|
| 433 |
return request
|
| 434 |
}
|
|
|
|
| 430 |
Transactions: data.TrustedBatch.BatchL2Data,
|
| 431 |
ForkID: b.state.GetForkIDByBatchNumber(uint64(data.TrustedBatch.Number)),
|
| 432 |
SkipVerifyL1InfoRoot_V2: true,
|
| 433 |
+
ExecutionMode: executor.ExecutionMode1,
|
| 434 |
}
|
| 435 |
return request
|
| 436 |
}
|
|
@@ -196,6 +196,7 @@
|
|
| 196 |
OldAccInputHash: batches[1].AccInputHash,
|
| 197 |
Coinbase: common.HexToAddress(trustedBatch.Coinbase.String()),
|
| 198 |
Timestamp_V1: time.Unix(int64(trustedBatch.Timestamp), 0),
|
|
|
|
| 199 |
}
|
| 200 |
// check if batch needs to be synchronized
|
| 201 |
if batches[0] != nil {
|
|
|
|
| 196 |
OldAccInputHash: batches[1].AccInputHash,
|
| 197 |
Coinbase: common.HexToAddress(trustedBatch.Coinbase.String()),
|
| 198 |
Timestamp_V1: time.Unix(int64(trustedBatch.Timestamp), 0),
|
| 199 |
+
ExecutionMode: executor.ExecutionMode1,
|
| 200 |
}
|
| 201 |
// check if batch needs to be synchronized
|
| 202 |
if batches[0] != nil {
|
|
@@ -1,166 +0,0 @@
|
|
| 1 |
-
package synchronizer
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
| 12 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1event_orders"
|
| 13 |
-
"github.com/ethereum/go-ethereum/common"
|
| 14 |
-
"github.com/jackc/pgx/v4"
|
| 15 |
-
)
|
| 16 |
-
|
| 17 |
-
type stateBlockRangeProcessor interface {
|
| 18 |
-
BeginStateTransaction(ctx context.Context) (pgx.Tx, error)
|
| 19 |
-
AddBlock(ctx context.Context, block *state.Block, dbTx pgx.Tx) error
|
| 20 |
-
GetForkIDByBatchNumber(batchNumber uint64) uint64
|
| 21 |
-
GetForkIDByBlockNumber(blockNumber uint64) uint64
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
type ethermanI interface {
|
| 25 |
-
GetFinalizedBlockNumber(ctx context.Context) (uint64, error)
|
| 26 |
-
}
|
| 27 |
-
|
| 28 |
-
// BlockRangeProcess is the struct that process the block range that implements syncinterfaces.BlockRangeProcessor
|
| 29 |
-
type BlockRangeProcess struct {
|
| 30 |
-
state stateBlockRangeProcessor
|
| 31 |
-
etherMan ethermanI
|
| 32 |
-
l1EventProcessors syncinterfaces.L1EventProcessorManager
|
| 33 |
-
flushIdManager syncinterfaces.SynchronizerFlushIDManager
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
// NewBlockRangeProcessLegacy creates a new BlockRangeProcess
|
| 37 |
-
func NewBlockRangeProcessLegacy(
|
| 38 |
-
state stateBlockRangeProcessor,
|
| 39 |
-
etherMan ethermanI,
|
| 40 |
-
l1EventProcessors syncinterfaces.L1EventProcessorManager,
|
| 41 |
-
flushIdManager syncinterfaces.SynchronizerFlushIDManager,
|
| 42 |
-
) *BlockRangeProcess {
|
| 43 |
-
return &BlockRangeProcess{
|
| 44 |
-
state: state,
|
| 45 |
-
etherMan: etherMan,
|
| 46 |
-
l1EventProcessors: l1EventProcessors,
|
| 47 |
-
flushIdManager: flushIdManager,
|
| 48 |
-
}
|
| 49 |
-
}
|
| 50 |
-
|
| 51 |
-
// ProcessBlockRangeSingleDbTx process the L1 events and stores the information in the db reusing same DbTx
|
| 52 |
-
func (s *BlockRangeProcess) ProcessBlockRangeSingleDbTx(ctx context.Context, blocks []etherman.Block, order map[common.Hash][]etherman.Order, storeBlocks syncinterfaces.ProcessBlockRangeL1BlocksMode, dbTx pgx.Tx) error {
|
| 53 |
-
return s.internalProcessBlockRange(ctx, blocks, order, storeBlocks, &dbTx)
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
// ProcessBlockRange process the L1 events and stores the information in the db
|
| 57 |
-
func (s *BlockRangeProcess) ProcessBlockRange(ctx context.Context, blocks []etherman.Block, order map[common.Hash][]etherman.Order) error {
|
| 58 |
-
return s.internalProcessBlockRange(ctx, blocks, order, syncinterfaces.StoreL1Blocks, nil)
|
| 59 |
-
}
|
| 60 |
-
|
| 61 |
-
// ProcessBlockRange process the L1 events and stores the information in the db
|
| 62 |
-
func (s *BlockRangeProcess) internalProcessBlockRange(ctx context.Context, blocks []etherman.Block, order map[common.Hash][]etherman.Order, storeBlocks syncinterfaces.ProcessBlockRangeL1BlocksMode, dbTxExt *pgx.Tx) error {
|
| 63 |
-
// Check the latest finalized block in L1
|
| 64 |
-
finalizedBlockNumber, err := s.etherMan.GetFinalizedBlockNumber(ctx)
|
| 65 |
-
if err != nil {
|
| 66 |
-
log.Errorf("error getting finalized block number in L1. Error: %v", err)
|
| 67 |
-
return err
|
| 68 |
-
}
|
| 69 |
-
// New info has to be included into the db using the state
|
| 70 |
-
for i := range blocks {
|
| 71 |
-
// Begin db transaction
|
| 72 |
-
var dbTx pgx.Tx
|
| 73 |
-
var err error
|
| 74 |
-
if dbTxExt == nil {
|
| 75 |
-
log.Debugf("Starting dbTx for BlockNumber:%d", blocks[i].BlockNumber)
|
| 76 |
-
dbTx, err = s.state.BeginStateTransaction(ctx)
|
| 77 |
-
if err != nil {
|
| 78 |
-
return err
|
| 79 |
-
}
|
| 80 |
-
} else {
|
| 81 |
-
dbTx = *dbTxExt
|
| 82 |
-
}
|
| 83 |
-
// Process event received from l1
|
| 84 |
-
err = s.processBlock(ctx, blocks, i, dbTx, order, storeBlocks, finalizedBlockNumber)
|
| 85 |
-
if err != nil {
|
| 86 |
-
if dbTxExt == nil {
|
| 87 |
-
// Rollback db transaction
|
| 88 |
-
rollbackErr := dbTx.Rollback(ctx)
|
| 89 |
-
if rollbackErr != nil {
|
| 90 |
-
if !errors.Is(rollbackErr, pgx.ErrTxClosed) {
|
| 91 |
-
log.Errorf("error rolling back state. RollbackErr: %s, Error : %v", rollbackErr.Error(), err)
|
| 92 |
-
return rollbackErr
|
| 93 |
-
} else {
|
| 94 |
-
log.Warnf("error rolling back state because is already closed. RollbackErr: %s, Error : %v", rollbackErr.Error(), err)
|
| 95 |
-
return err
|
| 96 |
-
}
|
| 97 |
-
}
|
| 98 |
-
return err
|
| 99 |
-
}
|
| 100 |
-
return err
|
| 101 |
-
}
|
| 102 |
-
if dbTxExt == nil {
|
| 103 |
-
// Commit db transaction
|
| 104 |
-
err = dbTx.Commit(ctx)
|
| 105 |
-
if err != nil {
|
| 106 |
-
log.Errorf("error committing state. BlockNumber: %d, Error: %v", blocks[i].BlockNumber, err)
|
| 107 |
-
}
|
| 108 |
-
}
|
| 109 |
-
}
|
| 110 |
-
return nil
|
| 111 |
-
}
|
| 112 |
-
|
| 113 |
-
func (s *BlockRangeProcess) processBlock(ctx context.Context, blocks []etherman.Block, i int, dbTx pgx.Tx, order map[common.Hash][]etherman.Order, storeBlock syncinterfaces.ProcessBlockRangeL1BlocksMode, finalizedBlockNumber uint64) error {
|
| 114 |
-
var err error
|
| 115 |
-
if storeBlock == syncinterfaces.StoreL1Blocks {
|
| 116 |
-
b := state.Block{
|
| 117 |
-
BlockNumber: blocks[i].BlockNumber,
|
| 118 |
-
BlockHash: blocks[i].BlockHash,
|
| 119 |
-
ParentHash: blocks[i].ParentHash,
|
| 120 |
-
ReceivedAt: blocks[i].ReceivedAt,
|
| 121 |
-
}
|
| 122 |
-
if blocks[i].BlockNumber <= finalizedBlockNumber {
|
| 123 |
-
b.Checked = true
|
| 124 |
-
}
|
| 125 |
-
err = s.state.AddBlock(ctx, &b, dbTx)
|
| 126 |
-
if err != nil {
|
| 127 |
-
log.Errorf("error adding block to db. BlockNumber: %d, error: %v", blocks[i].BlockNumber, err)
|
| 128 |
-
return err
|
| 129 |
-
}
|
| 130 |
-
} else {
|
| 131 |
-
log.Debugf("Skip storing block BlockNumber:%d", blocks[i].BlockNumber)
|
| 132 |
-
}
|
| 133 |
-
for _, element := range order[blocks[i].BlockHash] {
|
| 134 |
-
err := s.processElement(ctx, element, blocks, i, dbTx)
|
| 135 |
-
if err != nil {
|
| 136 |
-
return err
|
| 137 |
-
}
|
| 138 |
-
}
|
| 139 |
-
log.Debug("Checking FlushID to commit L1 data to db")
|
| 140 |
-
err = s.flushIdManager.CheckFlushID(dbTx)
|
| 141 |
-
if err != nil {
|
| 142 |
-
log.Errorf("error checking flushID. BlockNumber: %d, Error: %v", blocks[i].BlockNumber, err)
|
| 143 |
-
return err
|
| 144 |
-
}
|
| 145 |
-
return nil
|
| 146 |
-
}
|
| 147 |
-
|
| 148 |
-
func (s *BlockRangeProcess) processElement(ctx context.Context, element etherman.Order, blocks []etherman.Block, i int, dbTx pgx.Tx) error {
|
| 149 |
-
batchSequence := l1event_orders.GetSequenceFromL1EventOrder(element.Name, &blocks[i], element.Pos)
|
| 150 |
-
var forkId uint64
|
| 151 |
-
if batchSequence != nil {
|
| 152 |
-
forkId = s.state.GetForkIDByBatchNumber(batchSequence.FromBatchNumber)
|
| 153 |
-
log.Debug("EventOrder: ", element.Name, ". Batch Sequence: ", batchSequence, "forkId: ", forkId)
|
| 154 |
-
} else {
|
| 155 |
-
forkId = s.state.GetForkIDByBlockNumber(blocks[i].BlockNumber)
|
| 156 |
-
log.Debug("EventOrder: ", element.Name, ". BlockNumber: ", blocks[i].BlockNumber, "forkId: ", forkId)
|
| 157 |
-
}
|
| 158 |
-
forkIdTyped := actions.ForkIdType(forkId)
|
| 159 |
-
|
| 160 |
-
err := s.l1EventProcessors.Process(ctx, forkIdTyped, element, &blocks[i], dbTx)
|
| 161 |
-
if err != nil {
|
| 162 |
-
log.Error("error l1EventProcessors.Process: ", err)
|
| 163 |
-
return err
|
| 164 |
-
}
|
| 165 |
-
return nil
|
| 166 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -79,8 +79,6 @@
|
|
| 79 |
syncTrustedStateExecutor syncinterfaces.SyncTrustedStateExecutor
|
| 80 |
halter syncinterfaces.CriticalErrorHandler
|
| 81 |
asyncL1BlockChecker syncinterfaces.L1BlockCheckerIntegrator
|
| 82 |
-
blockRangeProcessor syncinterfaces.BlockRangeProcessor
|
| 83 |
-
syncPreRollup syncinterfaces.SyncPreRollupSyncer
|
| 84 |
}
|
| 85 |
|
| 86 |
// NewSynchronizer creates and initializes an instance of Synchronizer
|
|
@@ -168,9 +166,9 @@
|
|
| 168 |
|
| 169 |
syncTrustedStateEtrog := l2_shared.NewTrustedBatchesRetrieve(executor, zkEVMClient, res.state, *sync, *l2_shared.NewTrustedStateManager(syncCommon.DefaultTimeProvider{}, timeOfLiveBatchOnCache))
|
| 170 |
res.syncTrustedStateExecutor = l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{
|
| 171 |
-
uint64(state.FORKID_ETROG):
|
| 172 |
-
uint64(state.FORKID_ELDERBERRY):
|
| 173 |
-
uint64(state.
|
| 174 |
}, res.state)
|
| 175 |
}
|
| 176 |
var l1checkerL2Blocks *actions.CheckL2BlockHash
|
|
@@ -185,7 +183,7 @@
|
|
| 185 |
log.Errorf("error getting last L2Block number from state. Error: %v", err)
|
| 186 |
return nil, err
|
| 187 |
}
|
| 188 |
-
l1checkerL2Blocks, err = actions.NewCheckL2BlockHash(res.state, res.zkEVMClientEthereumCompatible, initialL2Block, cfg.
|
| 189 |
if err != nil {
|
| 190 |
log.Error("error creating new instance of checkL2BlockHash. Error: ", err)
|
| 191 |
return nil, err
|
|
@@ -196,8 +194,6 @@
|
|
| 196 |
}
|
| 197 |
|
| 198 |
res.l1EventProcessors = defaultsL1EventProcessors(res, l1checkerL2Blocks)
|
| 199 |
-
res.blockRangeProcessor = NewBlockRangeProcessLegacy(st, ethMan, res.l1EventProcessors, res)
|
| 200 |
-
res.syncPreRollup = NewSyncPreRollup(ethMan, st, res.blockRangeProcessor, cfg.SyncChunkSize, genesis.BlockNumber)
|
| 201 |
switch cfg.L1SynchronizationMode {
|
| 202 |
case ParallelMode:
|
| 203 |
log.Info("L1SynchronizationMode is parallel")
|
|
@@ -232,7 +228,7 @@
|
|
| 232 |
ApplyAfterNumRollupReceived: cfg.L1ParallelSynchronization.PerformanceWarning.ApplyAfterNumRollupReceived,
|
| 233 |
AceptableInacctivityTime: cfg.L1ParallelSynchronization.PerformanceWarning.AceptableInacctivityTime.Duration,
|
| 234 |
}
|
| 235 |
-
L1DataProcessor := l1_parallel_sync.NewL1RollupInfoConsumer(cfgConsumer, sync
|
| 236 |
|
| 237 |
cfgProducer := l1_parallel_sync.ConfigProducer{
|
| 238 |
SyncChunkSize: cfg.SyncChunkSize,
|
|
@@ -279,91 +275,8 @@
|
|
| 279 |
return err
|
| 280 |
}
|
| 281 |
|
| 282 |
-
func (s *ClientSynchronizer) isGenesisProcessed(ctx context.Context, dbTx pgx.Tx) (bool, *state.Block, error) {
|
| 283 |
-
lastEthBlockSynced, err := s.state.GetLastBlock(ctx, dbTx)
|
| 284 |
-
if err != nil && errors.Is(err, state.ErrStateNotSynchronized) {
|
| 285 |
-
return false, lastEthBlockSynced, nil
|
| 286 |
-
}
|
| 287 |
-
|
| 288 |
-
if lastEthBlockSynced.BlockNumber >= s.genesis.BlockNumber {
|
| 289 |
-
log.Infof("Genesis block processed. Last block synced: %d >= genesis %d", lastEthBlockSynced.BlockNumber, s.genesis.BlockNumber)
|
| 290 |
-
return true, lastEthBlockSynced, nil
|
| 291 |
-
}
|
| 292 |
-
log.Warnf("Genesis block not processed yet. Last block synced: %d < genesis %d", lastEthBlockSynced.BlockNumber, s.genesis.BlockNumber)
|
| 293 |
-
return false, lastEthBlockSynced, nil
|
| 294 |
-
}
|
| 295 |
-
|
| 296 |
-
func (s *ClientSynchronizer) processGenesis() (*state.Block, error) {
|
| 297 |
-
log.Info("State is empty, verifying genesis block")
|
| 298 |
-
valid, err := s.etherMan.VerifyGenBlockNumber(s.ctx, s.genesis.BlockNumber)
|
| 299 |
-
if err != nil {
|
| 300 |
-
log.Error("error checking genesis block number. Error: ", err)
|
| 301 |
-
return nil, err
|
| 302 |
-
} else if !valid {
|
| 303 |
-
log.Error("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")
|
| 304 |
-
return nil, fmt.Errorf("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")
|
| 305 |
-
}
|
| 306 |
-
// Sync pre genesis rollup events
|
| 307 |
-
s.syncPreRollup.(*SyncPreRollup).GenesisBlockNumber = s.genesis.BlockNumber
|
| 308 |
-
err = s.syncPreRollup.SynchronizePreGenesisRollupEvents(s.ctx)
|
| 309 |
-
if err != nil {
|
| 310 |
-
log.Error("error synchronizing pre genesis rollup events: ", err)
|
| 311 |
-
return nil, err
|
| 312 |
-
}
|
| 313 |
-
log.Info("Setting genesis block")
|
| 314 |
-
header, err := s.etherMan.HeaderByNumber(s.ctx, big.NewInt(0).SetUint64(s.genesis.BlockNumber))
|
| 315 |
-
if err != nil {
|
| 316 |
-
log.Errorf("error getting l1 block header for block %d. Error: %v", s.genesis.BlockNumber, err)
|
| 317 |
-
return nil, err
|
| 318 |
-
}
|
| 319 |
-
lastEthBlockSynced := &state.Block{
|
| 320 |
-
BlockNumber: header.Number.Uint64(),
|
| 321 |
-
BlockHash: header.Hash(),
|
| 322 |
-
ParentHash: header.ParentHash,
|
| 323 |
-
ReceivedAt: time.Unix(int64(header.Time), 0),
|
| 324 |
-
}
|
| 325 |
-
dbTx, err := s.state.BeginStateTransaction(s.ctx)
|
| 326 |
-
if err != nil {
|
| 327 |
-
log.Errorf("error creating db transaction to get latest block. Error: %v", err)
|
| 328 |
-
return nil, err
|
| 329 |
-
}
|
| 330 |
-
genesisRoot, err := s.state.SetGenesis(s.ctx, *lastEthBlockSynced, s.genesis, stateMetrics.SynchronizerCallerLabel, dbTx)
|
| 331 |
-
if err != nil {
|
| 332 |
-
log.Error("error setting genesis: ", err)
|
| 333 |
-
return nil, rollback(s.ctx, dbTx, err)
|
| 334 |
-
}
|
| 335 |
-
err = s.RequestAndProcessRollupGenesisBlock(dbTx, lastEthBlockSynced)
|
| 336 |
-
if err != nil {
|
| 337 |
-
log.Error("error processing Rollup genesis block: ", err)
|
| 338 |
-
return nil, rollback(s.ctx, dbTx, err)
|
| 339 |
-
}
|
| 340 |
-
|
| 341 |
-
if genesisRoot != s.genesis.Root {
|
| 342 |
-
log.Errorf("Calculated newRoot should be %s instead of %s", s.genesis.Root.String(), genesisRoot.String())
|
| 343 |
-
return nil, rollback(s.ctx, dbTx, err)
|
| 344 |
-
}
|
| 345 |
-
// Waiting for the flushID to be stored
|
| 346 |
-
err = s.checkFlushID(dbTx)
|
| 347 |
-
if err != nil {
|
| 348 |
-
log.Error("error checking genesis flushID: ", err)
|
| 349 |
-
return nil, rollback(s.ctx, dbTx, err)
|
| 350 |
-
}
|
| 351 |
-
if err := dbTx.Commit(s.ctx); err != nil {
|
| 352 |
-
log.Errorf("error genesis committing dbTx, err: %v", err)
|
| 353 |
-
return nil, rollback(s.ctx, dbTx, err)
|
| 354 |
-
}
|
| 355 |
-
log.Info("Genesis root matches! Stored genesis blocks.")
|
| 356 |
-
return lastEthBlockSynced, nil
|
| 357 |
-
}
|
| 358 |
-
|
| 359 |
// Sync function will read the last state synced and will continue from that point.
|
| 360 |
// Sync() will read blockchain events to detect rollup updates
|
| 361 |
-
// 1. Check if genesisProcess is done
|
| 362 |
-
// 2. If not, process genesis
|
| 363 |
-
// 2.1 -There are blocks previous to the genesis block? -> go on with process of InfoRootTree
|
| 364 |
-
// 2.2 -There are no blocks previous to the genesis block? -> get ETROG Upgrade block and start there to process of InfoRootTree
|
| 365 |
-
// 3. Setup genesis data
|
| 366 |
-
// 4. Start sync as usual
|
| 367 |
func (s *ClientSynchronizer) Sync() error {
|
| 368 |
startInitialization := time.Now()
|
| 369 |
// If there is no lastEthereumBlock means that sync from the beginning is necessary. If not, it continues from the retrieved ethereum block
|
|
@@ -378,19 +291,92 @@
|
|
| 378 |
log.Errorf("error creating db transaction to get latest block. Error: %v", err)
|
| 379 |
return err
|
| 380 |
}
|
| 381 |
-
|
| 382 |
if err != nil {
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
return err
|
| 391 |
}
|
| 392 |
}
|
| 393 |
-
|
| 394 |
initBatchNumber, err := s.state.GetLastBatchNumber(s.ctx, dbTx)
|
| 395 |
if err != nil {
|
| 396 |
log.Error("error getting latest batchNumber synced. Error: ", err)
|
|
@@ -622,7 +608,7 @@
|
|
| 622 |
|
| 623 |
for {
|
| 624 |
if toBlock > lastKnownBlock.Uint64() {
|
| 625 |
-
log.Debug("Setting toBlock to the lastKnownBlock
|
| 626 |
toBlock = lastKnownBlock.Uint64()
|
| 627 |
}
|
| 628 |
if fromBlock > toBlock {
|
|
@@ -690,7 +676,7 @@
|
|
| 690 |
}
|
| 691 |
|
| 692 |
start = time.Now()
|
| 693 |
-
err = s.
|
| 694 |
metrics.ProcessL1DataTime(time.Since(start))
|
| 695 |
if err != nil {
|
| 696 |
return lastEthBlockSynced, err
|
|
@@ -1013,7 +999,7 @@
|
|
| 1013 |
log.Infof("[checkReorg function] reorgedBlockNumber: %d reorgedBlockHash already synced: %s", reorgedBlock.BlockNumber, reorgedBlock.BlockHash.String())
|
| 1014 |
|
| 1015 |
// Compare hashes
|
| 1016 |
-
if (block.BlockHash != reorgedBlock.BlockHash || block.ParentHash != reorgedBlock.ParentHash) && reorgedBlock.BlockNumber > s.genesis.
|
| 1017 |
log.Infof("checkReorg: Bad block %d hashOk %t parentHashOk %t", reorgedBlock.BlockNumber, block.BlockHash == reorgedBlock.BlockHash, block.ParentHash == reorgedBlock.ParentHash)
|
| 1018 |
log.Debug("[checkReorg function] => latestBlockNumber: ", reorgedBlock.BlockNumber)
|
| 1019 |
log.Debug("[checkReorg function] => latestBlockHash: ", reorgedBlock.BlockHash)
|
|
|
|
| 79 |
syncTrustedStateExecutor syncinterfaces.SyncTrustedStateExecutor
|
| 80 |
halter syncinterfaces.CriticalErrorHandler
|
| 81 |
asyncL1BlockChecker syncinterfaces.L1BlockCheckerIntegrator
|
|
|
|
|
|
|
| 82 |
}
|
| 83 |
|
| 84 |
// NewSynchronizer creates and initializes an instance of Synchronizer
|
|
|
|
| 166 |
|
| 167 |
syncTrustedStateEtrog := l2_shared.NewTrustedBatchesRetrieve(executor, zkEVMClient, res.state, *sync, *l2_shared.NewTrustedStateManager(syncCommon.DefaultTimeProvider{}, timeOfLiveBatchOnCache))
|
| 168 |
res.syncTrustedStateExecutor = l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{
|
| 169 |
+
uint64(state.FORKID_ETROG): syncTrustedStateEtrog,
|
| 170 |
+
uint64(state.FORKID_ELDERBERRY): syncTrustedStateEtrog,
|
| 171 |
+
uint64(state.FORKID_9): syncTrustedStateEtrog,
|
| 172 |
}, res.state)
|
| 173 |
}
|
| 174 |
var l1checkerL2Blocks *actions.CheckL2BlockHash
|
|
|
|
| 183 |
log.Errorf("error getting last L2Block number from state. Error: %v", err)
|
| 184 |
return nil, err
|
| 185 |
}
|
| 186 |
+
l1checkerL2Blocks, err = actions.NewCheckL2BlockHash(res.state, res.zkEVMClientEthereumCompatible, initialL2Block, cfg.L1SyncCheckL2BlockNumberhModulus)
|
| 187 |
if err != nil {
|
| 188 |
log.Error("error creating new instance of checkL2BlockHash. Error: ", err)
|
| 189 |
return nil, err
|
|
|
|
| 194 |
}
|
| 195 |
|
| 196 |
res.l1EventProcessors = defaultsL1EventProcessors(res, l1checkerL2Blocks)
|
|
|
|
|
|
|
| 197 |
switch cfg.L1SynchronizationMode {
|
| 198 |
case ParallelMode:
|
| 199 |
log.Info("L1SynchronizationMode is parallel")
|
|
|
|
| 228 |
ApplyAfterNumRollupReceived: cfg.L1ParallelSynchronization.PerformanceWarning.ApplyAfterNumRollupReceived,
|
| 229 |
AceptableInacctivityTime: cfg.L1ParallelSynchronization.PerformanceWarning.AceptableInacctivityTime.Duration,
|
| 230 |
}
|
| 231 |
+
L1DataProcessor := l1_parallel_sync.NewL1RollupInfoConsumer(cfgConsumer, sync, chIncommingRollupInfo)
|
| 232 |
|
| 233 |
cfgProducer := l1_parallel_sync.ConfigProducer{
|
| 234 |
SyncChunkSize: cfg.SyncChunkSize,
|
|
|
|
| 275 |
return err
|
| 276 |
}
|
| 277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
// Sync function will read the last state synced and will continue from that point.
|
| 279 |
// Sync() will read blockchain events to detect rollup updates
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
func (s *ClientSynchronizer) Sync() error {
|
| 281 |
startInitialization := time.Now()
|
| 282 |
// If there is no lastEthereumBlock means that sync from the beginning is necessary. If not, it continues from the retrieved ethereum block
|
|
|
|
| 291 |
log.Errorf("error creating db transaction to get latest block. Error: %v", err)
|
| 292 |
return err
|
| 293 |
}
|
| 294 |
+
lastEthBlockSynced, err := s.state.GetLastBlock(s.ctx, dbTx)
|
| 295 |
if err != nil {
|
| 296 |
+
if errors.Is(err, state.ErrStateNotSynchronized) {
|
| 297 |
+
log.Info("State is empty, verifying genesis block")
|
| 298 |
+
valid, err := s.etherMan.VerifyGenBlockNumber(s.ctx, s.genesis.RollupBlockNumber)
|
| 299 |
+
if err != nil {
|
| 300 |
+
log.Error("error checking genesis block number. Error: ", err)
|
| 301 |
+
return rollback(s.ctx, dbTx, err)
|
| 302 |
+
} else if !valid {
|
| 303 |
+
log.Error("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")
|
| 304 |
+
return rollback(s.ctx, dbTx, fmt.Errorf("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed"))
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
// Sync events from RollupManager that happen before rollup creation
|
| 308 |
+
log.Info("synchronizing events from RollupManager that happen before rollup creation")
|
| 309 |
+
for i := s.genesis.RollupManagerBlockNumber; true; i += s.cfg.SyncChunkSize {
|
| 310 |
+
toBlock := min(i+s.cfg.SyncChunkSize-1, s.genesis.RollupBlockNumber-1)
|
| 311 |
+
blocks, order, err := s.etherMan.GetRollupInfoByBlockRange(s.ctx, i, &toBlock)
|
| 312 |
+
if err != nil {
|
| 313 |
+
log.Error("error getting rollupInfoByBlockRange before rollup genesis: ", err)
|
| 314 |
+
rollbackErr := dbTx.Rollback(s.ctx)
|
| 315 |
+
if rollbackErr != nil {
|
| 316 |
+
log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
|
| 317 |
+
return rollbackErr
|
| 318 |
+
}
|
| 319 |
+
return err
|
| 320 |
+
}
|
| 321 |
+
err = s.ProcessBlockRange(blocks, order)
|
| 322 |
+
if err != nil {
|
| 323 |
+
log.Error("error processing blocks before the genesis: ", err)
|
| 324 |
+
rollbackErr := dbTx.Rollback(s.ctx)
|
| 325 |
+
if rollbackErr != nil {
|
| 326 |
+
log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
|
| 327 |
+
return rollbackErr
|
| 328 |
+
}
|
| 329 |
+
return err
|
| 330 |
+
}
|
| 331 |
+
if toBlock == s.genesis.RollupBlockNumber-1 {
|
| 332 |
+
break
|
| 333 |
+
}
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
header, err := s.etherMan.HeaderByNumber(s.ctx, big.NewInt(0).SetUint64(s.genesis.RollupBlockNumber))
|
| 337 |
+
if err != nil {
|
| 338 |
+
log.Errorf("error getting l1 block header for block %d. Error: %v", s.genesis.RollupBlockNumber, err)
|
| 339 |
+
return rollback(s.ctx, dbTx, err)
|
| 340 |
+
}
|
| 341 |
+
log.Info("synchronizing rollup creation block")
|
| 342 |
+
lastEthBlockSynced = &state.Block{
|
| 343 |
+
BlockNumber: header.Number.Uint64(),
|
| 344 |
+
BlockHash: header.Hash(),
|
| 345 |
+
ParentHash: header.ParentHash,
|
| 346 |
+
ReceivedAt: time.Unix(int64(header.Time), 0),
|
| 347 |
+
}
|
| 348 |
+
genesisRoot, err := s.state.SetGenesis(s.ctx, *lastEthBlockSynced, s.genesis, stateMetrics.SynchronizerCallerLabel, dbTx)
|
| 349 |
+
if err != nil {
|
| 350 |
+
log.Error("error setting genesis: ", err)
|
| 351 |
+
return rollback(s.ctx, dbTx, err)
|
| 352 |
+
}
|
| 353 |
+
err = s.RequestAndProcessRollupGenesisBlock(dbTx, lastEthBlockSynced)
|
| 354 |
+
if err != nil {
|
| 355 |
+
log.Error("error processing Rollup genesis block: ", err)
|
| 356 |
+
return rollback(s.ctx, dbTx, err)
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
if genesisRoot != s.genesis.Root {
|
| 360 |
+
log.Errorf("Calculated newRoot should be %s instead of %s", s.genesis.Root.String(), genesisRoot.String())
|
| 361 |
+
return rollback(s.ctx, dbTx, fmt.Errorf("calculated newRoot should be %s instead of %s", s.genesis.Root.String(), genesisRoot.String()))
|
| 362 |
+
}
|
| 363 |
+
// Waiting for the flushID to be stored
|
| 364 |
+
err = s.checkFlushID(dbTx)
|
| 365 |
+
if err != nil {
|
| 366 |
+
log.Error("error checking genesis flushID: ", err)
|
| 367 |
+
return rollback(s.ctx, dbTx, err)
|
| 368 |
+
}
|
| 369 |
+
log.Debug("Genesis root matches!")
|
| 370 |
+
} else {
|
| 371 |
+
log.Error("unexpected error getting the latest ethereum block. Error: ", err)
|
| 372 |
+
rollbackErr := dbTx.Rollback(s.ctx)
|
| 373 |
+
if rollbackErr != nil {
|
| 374 |
+
log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
|
| 375 |
+
return rollbackErr
|
| 376 |
+
}
|
| 377 |
return err
|
| 378 |
}
|
| 379 |
}
|
|
|
|
| 380 |
initBatchNumber, err := s.state.GetLastBatchNumber(s.ctx, dbTx)
|
| 381 |
if err != nil {
|
| 382 |
log.Error("error getting latest batchNumber synced. Error: ", err)
|
|
|
|
| 608 |
|
| 609 |
for {
|
| 610 |
if toBlock > lastKnownBlock.Uint64() {
|
| 611 |
+
log.Debug("Setting toBlock to the lastKnownBlock")
|
| 612 |
toBlock = lastKnownBlock.Uint64()
|
| 613 |
}
|
| 614 |
if fromBlock > toBlock {
|
|
|
|
| 676 |
}
|
| 677 |
|
| 678 |
start = time.Now()
|
| 679 |
+
err = s.ProcessBlockRange(blocks, order)
|
| 680 |
metrics.ProcessL1DataTime(time.Since(start))
|
| 681 |
if err != nil {
|
| 682 |
return lastEthBlockSynced, err
|
|
|
|
| 999 |
log.Infof("[checkReorg function] reorgedBlockNumber: %d reorgedBlockHash already synced: %s", reorgedBlock.BlockNumber, reorgedBlock.BlockHash.String())
|
| 1000 |
|
| 1001 |
// Compare hashes
|
| 1002 |
+
if (block.BlockHash != reorgedBlock.BlockHash || block.ParentHash != reorgedBlock.ParentHash) && reorgedBlock.BlockNumber > s.genesis.RollupBlockNumber {
|
| 1003 |
log.Infof("checkReorg: Bad block %d hashOk %t parentHashOk %t", reorgedBlock.BlockNumber, block.BlockHash == reorgedBlock.BlockHash, block.ParentHash == reorgedBlock.ParentHash)
|
| 1004 |
log.Debug("[checkReorg function] => latestBlockNumber: ", reorgedBlock.BlockNumber)
|
| 1005 |
log.Debug("[checkReorg function] => latestBlockHash: ", reorgedBlock.BlockHash)
|
|
@@ -1,122 +0,0 @@
|
|
| 1 |
-
package synchronizer
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
"time"
|
| 7 |
-
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 11 |
-
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
| 12 |
-
"github.com/jackc/pgx/v4"
|
| 13 |
-
)
|
| 14 |
-
|
| 15 |
-
const (
|
| 16 |
-
pregenesisSyncLogPrefix = "sync pregenesis:"
|
| 17 |
-
)
|
| 18 |
-
|
| 19 |
-
// SyncPreRollup is the struct for synchronizing pre genesis rollup events.
|
| 20 |
-
// Implements: syncinterfaces.SyncPreRollupSyncer
|
| 21 |
-
type SyncPreRollup struct {
|
| 22 |
-
etherman syncinterfaces.EthermanPreRollup
|
| 23 |
-
state syncinterfaces.StateLastBlockGetter
|
| 24 |
-
blockRangeProcessor syncinterfaces.BlockRangeProcessor
|
| 25 |
-
SyncChunkSize uint64
|
| 26 |
-
GenesisBlockNumber uint64
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
// NewSyncPreRollup creates a new SyncPreRollup
|
| 30 |
-
func NewSyncPreRollup(
|
| 31 |
-
etherman syncinterfaces.EthermanPreRollup,
|
| 32 |
-
state syncinterfaces.StateLastBlockGetter,
|
| 33 |
-
blockRangeProcessor syncinterfaces.BlockRangeProcessor,
|
| 34 |
-
syncChunkSize uint64,
|
| 35 |
-
genesisBlockNumber uint64,
|
| 36 |
-
) *SyncPreRollup {
|
| 37 |
-
return &SyncPreRollup{
|
| 38 |
-
etherman: etherman,
|
| 39 |
-
state: state,
|
| 40 |
-
blockRangeProcessor: blockRangeProcessor,
|
| 41 |
-
SyncChunkSize: syncChunkSize,
|
| 42 |
-
GenesisBlockNumber: genesisBlockNumber,
|
| 43 |
-
}
|
| 44 |
-
}
|
| 45 |
-
|
| 46 |
-
// SynchronizePreGenesisRollupEvents sync pre-rollup events
|
| 47 |
-
func (s *SyncPreRollup) SynchronizePreGenesisRollupEvents(ctx context.Context) error {
|
| 48 |
-
// Sync events from RollupManager that happen before rollup creation
|
| 49 |
-
log.Info(pregenesisSyncLogPrefix + "synchronizing events from RollupManager that happen before rollup creation")
|
| 50 |
-
needToUpdate, fromBlock, err := s.getStartingL1Block(ctx, nil)
|
| 51 |
-
if err != nil {
|
| 52 |
-
log.Errorf(pregenesisSyncLogPrefix+"error getting starting L1 block. Error: %v", err)
|
| 53 |
-
return err
|
| 54 |
-
}
|
| 55 |
-
if needToUpdate {
|
| 56 |
-
return s.ProcessL1InfoRootEvents(ctx, fromBlock, s.GenesisBlockNumber-1, s.SyncChunkSize)
|
| 57 |
-
} else {
|
| 58 |
-
log.Infof(pregenesisSyncLogPrefix+"No need to process blocks before the genesis block %d", s.GenesisBlockNumber)
|
| 59 |
-
return nil
|
| 60 |
-
}
|
| 61 |
-
}
|
| 62 |
-
|
| 63 |
-
// getStartingL1Block find if need to update and if yes the starting point:
|
| 64 |
-
// bool -> need to process blocks
|
| 65 |
-
// uint64 -> first block to synchronize
|
| 66 |
-
// error -> error
|
| 67 |
-
// 1. First try to get last block on DB, if there are could be fully synced or pending blocks
|
| 68 |
-
// 2. If DB is empty the LxLy upgrade block as starting point
|
| 69 |
-
func (s *SyncPreRollup) getStartingL1Block(ctx context.Context, dbTx pgx.Tx) (bool, uint64, error) {
|
| 70 |
-
lastBlock, err := s.state.GetLastBlock(ctx, dbTx)
|
| 71 |
-
if err != nil && errors.Is(err, state.ErrStateNotSynchronized) {
|
| 72 |
-
// No block on DB
|
| 73 |
-
upgradeLxLyBlockNumber, err := s.etherman.GetL1BlockUpgradeLxLy(ctx, s.GenesisBlockNumber)
|
| 74 |
-
if err != nil && errors.Is(err, etherman.ErrNotFound) {
|
| 75 |
-
log.Infof(pregenesisSyncLogPrefix+"LxLy upgrade not detected before genesis block %d, it'll be sync as usual. Nothing to do yet", s.GenesisBlockNumber)
|
| 76 |
-
return false, 0, nil
|
| 77 |
-
} else if err != nil {
|
| 78 |
-
log.Errorf(pregenesisSyncLogPrefix+"error getting LxLy upgrade block. Error: %v", err)
|
| 79 |
-
return false, 0, err
|
| 80 |
-
}
|
| 81 |
-
log.Infof(pregenesisSyncLogPrefix+"No block on DB, starting from LxLy upgrade block %d", upgradeLxLyBlockNumber)
|
| 82 |
-
return true, upgradeLxLyBlockNumber, nil
|
| 83 |
-
} else if err != nil {
|
| 84 |
-
log.Errorf("Error getting last Block on DB err:%v", err)
|
| 85 |
-
return false, 0, err
|
| 86 |
-
}
|
| 87 |
-
if lastBlock.BlockNumber >= s.GenesisBlockNumber-1 {
|
| 88 |
-
log.Warnf(pregenesisSyncLogPrefix+"Last block processed is %d, which is greater or equal than the previous genesis block %d", lastBlock, s.GenesisBlockNumber)
|
| 89 |
-
return false, 0, nil
|
| 90 |
-
}
|
| 91 |
-
log.Infof(pregenesisSyncLogPrefix+"Continue processing pre-genesis blocks, last block processed on DB is %d", lastBlock.BlockNumber)
|
| 92 |
-
return true, lastBlock.BlockNumber, nil
|
| 93 |
-
}
|
| 94 |
-
|
| 95 |
-
// ProcessL1InfoRootEvents processes the L1InfoRoot events for a range for L1 blocks
|
| 96 |
-
func (s *SyncPreRollup) ProcessL1InfoRootEvents(ctx context.Context, fromBlock uint64, toBlock uint64, syncChunkSize uint64) error {
|
| 97 |
-
startTime := time.Now()
|
| 98 |
-
log.Info(pregenesisSyncLogPrefix + "synchronizing L1InfoRoot events")
|
| 99 |
-
log.Infof(pregenesisSyncLogPrefix+"Starting syncing pre genesis LxLy events from block %d to block %d (total %d blocks)",
|
| 100 |
-
fromBlock, toBlock, toBlock-fromBlock+1)
|
| 101 |
-
for i := fromBlock; true; i += syncChunkSize {
|
| 102 |
-
toBlockReq := min(i+syncChunkSize-1, toBlock)
|
| 103 |
-
percent := float32(toBlockReq-fromBlock+1) * 100.0 / float32(toBlock-fromBlock+1) // nolint:gomnd
|
| 104 |
-
log.Infof(pregenesisSyncLogPrefix+"sync L1InfoTree events from %d to %d percent:%3.1f %% pending_blocks:%d", i, toBlockReq, percent, toBlock-toBlockReq)
|
| 105 |
-
blocks, order, err := s.etherman.GetRollupInfoByBlockRangePreviousRollupGenesis(ctx, i, &toBlockReq)
|
| 106 |
-
if err != nil {
|
| 107 |
-
log.Error(pregenesisSyncLogPrefix+"error getting rollupInfoByBlockRange before rollup genesis: ", err)
|
| 108 |
-
return err
|
| 109 |
-
}
|
| 110 |
-
err = s.blockRangeProcessor.ProcessBlockRange(ctx, blocks, order)
|
| 111 |
-
if err != nil {
|
| 112 |
-
log.Error(pregenesisSyncLogPrefix+"error processing blocks before the genesis: ", err)
|
| 113 |
-
return err
|
| 114 |
-
}
|
| 115 |
-
if toBlockReq == toBlock {
|
| 116 |
-
break
|
| 117 |
-
}
|
| 118 |
-
}
|
| 119 |
-
elapsedTime := time.Since(startTime)
|
| 120 |
-
log.Infof(pregenesisSyncLogPrefix+"sync L1InfoTree finish: from %d to %d total_block %d done in %s", fromBlock, toBlock, toBlock-fromBlock+1, &elapsedTime)
|
| 121 |
-
return nil
|
| 122 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,89 +0,0 @@
|
|
| 1 |
-
package synchronizer
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"testing"
|
| 6 |
-
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 10 |
-
mock_syncinterfaces "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces/mocks"
|
| 11 |
-
"github.com/ethereum/go-ethereum/common"
|
| 12 |
-
"github.com/stretchr/testify/mock"
|
| 13 |
-
"github.com/stretchr/testify/require"
|
| 14 |
-
)
|
| 15 |
-
|
| 16 |
-
func TestSyncPreRollupProcessL1InfoRootEventsAskForAllBlocks(t *testing.T) {
|
| 17 |
-
mockProcessor := mock_syncinterfaces.NewBlockRangeProcessor(t)
|
| 18 |
-
mockEtherman := mock_syncinterfaces.NewEthermanFullInterface(t)
|
| 19 |
-
sync := &SyncPreRollup{
|
| 20 |
-
etherman: mockEtherman,
|
| 21 |
-
blockRangeProcessor: mockProcessor,
|
| 22 |
-
SyncChunkSize: 10,
|
| 23 |
-
GenesisBlockNumber: 1234,
|
| 24 |
-
}
|
| 25 |
-
|
| 26 |
-
ctx := context.Background()
|
| 27 |
-
fromBlock := uint64(1)
|
| 28 |
-
toBlock := uint64(31)
|
| 29 |
-
syncChunkSize := uint64(10)
|
| 30 |
-
previousBlockNumber := uint64(1)
|
| 31 |
-
for _, i := range []uint64{10, 20, 30, 31} {
|
| 32 |
-
// Mocking the call to GetRollupInfoByBlockRangePreviousRollupGenesis
|
| 33 |
-
v := i
|
| 34 |
-
mockEtherman.EXPECT().GetRollupInfoByBlockRangePreviousRollupGenesis(ctx, previousBlockNumber, &v).
|
| 35 |
-
Return(getRollupTest()).Once()
|
| 36 |
-
previousBlockNumber = i + 1
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
mockProcessor.EXPECT().ProcessBlockRange(ctx, mock.Anything, mock.Anything).Return(nil).Maybe()
|
| 40 |
-
err := sync.ProcessL1InfoRootEvents(ctx, fromBlock, toBlock, syncChunkSize)
|
| 41 |
-
require.NoError(t, err)
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
func getRollupTest() ([]etherman.Block, map[common.Hash][]etherman.Order, error) {
|
| 45 |
-
return nil, nil, nil
|
| 46 |
-
}
|
| 47 |
-
|
| 48 |
-
func TestSyncPreRollupGetStartingL1Block(t *testing.T) {
|
| 49 |
-
mockState := mock_syncinterfaces.NewStateFullInterface(t)
|
| 50 |
-
mockEtherman := mock_syncinterfaces.NewEthermanFullInterface(t)
|
| 51 |
-
sync := &SyncPreRollup{
|
| 52 |
-
state: mockState,
|
| 53 |
-
etherman: mockEtherman,
|
| 54 |
-
GenesisBlockNumber: 1234,
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
ctx := context.Background()
|
| 58 |
-
|
| 59 |
-
for idx, testCase := range []struct {
|
| 60 |
-
name string
|
| 61 |
-
upgradeLxLyBlockNumber uint64
|
| 62 |
-
blockNumber uint64
|
| 63 |
-
expectedError bool
|
| 64 |
-
expectedNeedToUpdate bool
|
| 65 |
-
expectedBlockNumber uint64
|
| 66 |
-
}{
|
| 67 |
-
{name: "mid block", upgradeLxLyBlockNumber: 1000, blockNumber: 1001, expectedError: false, expectedNeedToUpdate: true, expectedBlockNumber: 1001},
|
| 68 |
-
{name: "pre block", upgradeLxLyBlockNumber: 1000, blockNumber: 999, expectedError: false, expectedNeedToUpdate: true, expectedBlockNumber: 999},
|
| 69 |
-
{name: "same genesis", upgradeLxLyBlockNumber: 1000, blockNumber: sync.GenesisBlockNumber, expectedError: false, expectedNeedToUpdate: false},
|
| 70 |
-
{name: "genesis-1", upgradeLxLyBlockNumber: 1000, blockNumber: 1233, expectedError: false, expectedNeedToUpdate: false},
|
| 71 |
-
} {
|
| 72 |
-
log.Info("Running test case ", idx+1)
|
| 73 |
-
block := state.Block{
|
| 74 |
-
BlockNumber: testCase.blockNumber,
|
| 75 |
-
}
|
| 76 |
-
mockEtherman.EXPECT().GetL1BlockUpgradeLxLy(ctx, sync.GenesisBlockNumber).Return(testCase.upgradeLxLyBlockNumber, nil).Maybe()
|
| 77 |
-
mockState.EXPECT().GetLastBlock(ctx, mock.Anything).Return(&block, nil).Once()
|
| 78 |
-
needToUpdate, blockNumber, err := sync.getStartingL1Block(ctx, nil)
|
| 79 |
-
if testCase.expectedError {
|
| 80 |
-
require.Error(t, err, testCase.name)
|
| 81 |
-
} else {
|
| 82 |
-
require.NoError(t, err, testCase.name)
|
| 83 |
-
require.Equal(t, testCase.expectedNeedToUpdate, needToUpdate, testCase.name)
|
| 84 |
-
if needToUpdate {
|
| 85 |
-
require.Equal(t, testCase.blockNumber, blockNumber, testCase.name)
|
| 86 |
-
}
|
| 87 |
-
}
|
| 88 |
-
}
|
| 89 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -31,7 +31,6 @@
|
|
| 31 |
ETROG_MODE_FLAG = true
|
| 32 |
RETRIEVE_BATCH_FROM_DB_FLAG = true
|
| 33 |
RETRIEVE_BATCH_FROM_CACHE_FLAG = false
|
| 34 |
-
PROCESS_BATCH_SELECTOR_ENABLED = false
|
| 35 |
)
|
| 36 |
|
| 37 |
type mocks struct {
|
|
@@ -123,7 +122,7 @@
|
|
| 123 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 124 |
func TestForcedBatchEtrog(t *testing.T) {
|
| 125 |
genesis := state.Genesis{
|
| 126 |
-
|
| 127 |
}
|
| 128 |
cfg := Config{
|
| 129 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
@@ -170,7 +169,6 @@
|
|
| 170 |
On("GetForkIDByBatchNumber", mock.Anything).
|
| 171 |
Return(uint64(7), nil).
|
| 172 |
Maybe()
|
| 173 |
-
|
| 174 |
m.State.
|
| 175 |
On("GetLastBlock", ctx, m.DbTx).
|
| 176 |
Return(lastBlock0, nil).
|
|
@@ -226,7 +224,7 @@
|
|
| 226 |
Coinbase: common.HexToAddress("0x222"),
|
| 227 |
SequencerAddr: common.HexToAddress("0x00"),
|
| 228 |
TxHash: common.HexToHash("0x333"),
|
| 229 |
-
PolygonRollupBaseEtrogBatchData: &
|
| 230 |
Transactions: []byte{},
|
| 231 |
ForcedGlobalExitRoot: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32},
|
| 232 |
ForcedTimestamp: uint64(t.Unix()),
|
|
@@ -397,7 +395,7 @@
|
|
| 397 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 398 |
func TestSequenceForcedBatchIncaberry(t *testing.T) {
|
| 399 |
genesis := state.Genesis{
|
| 400 |
-
|
| 401 |
}
|
| 402 |
cfg := Config{
|
| 403 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
@@ -490,7 +488,7 @@
|
|
| 490 |
BatchNumber: uint64(2),
|
| 491 |
Coinbase: common.HexToAddress("0x222"),
|
| 492 |
TxHash: common.HexToHash("0x333"),
|
| 493 |
-
PolygonRollupBaseEtrogBatchData:
|
| 494 |
Transactions: []byte{},
|
| 495 |
ForcedGlobalExitRoot: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32},
|
| 496 |
ForcedTimestamp: 1000, //ForcedBatch
|
|
@@ -659,7 +657,7 @@
|
|
| 659 |
|
| 660 |
func setupGenericTest(t *testing.T) (*state.Genesis, *Config, *mocks) {
|
| 661 |
genesis := state.Genesis{
|
| 662 |
-
|
| 663 |
}
|
| 664 |
cfg := Config{
|
| 665 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
@@ -761,11 +759,9 @@
|
|
| 761 |
transactions := []types.TransactionOrHash{}
|
| 762 |
for nBlock := 0; nBlock < howManyBlocks; nBlock++ {
|
| 763 |
block := state.L2BlockRaw{
|
| 764 |
-
|
| 765 |
-
|
| 766 |
-
|
| 767 |
-
},
|
| 768 |
-
Transactions: []state.L2TxRaw{},
|
| 769 |
}
|
| 770 |
for i := 0; i < howManyTx; i++ {
|
| 771 |
tx := createTransaction(uint64(i + 1))
|
|
@@ -925,7 +921,7 @@
|
|
| 925 |
|
| 926 |
func TestReorg(t *testing.T) {
|
| 927 |
genesis := state.Genesis{
|
| 928 |
-
|
| 929 |
}
|
| 930 |
cfg := Config{
|
| 931 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
@@ -1245,7 +1241,7 @@
|
|
| 1245 |
|
| 1246 |
func TestLatestSyncedBlockEmpty(t *testing.T) {
|
| 1247 |
genesis := state.Genesis{
|
| 1248 |
-
|
| 1249 |
}
|
| 1250 |
cfg := Config{
|
| 1251 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
@@ -1459,7 +1455,7 @@
|
|
| 1459 |
|
| 1460 |
func TestRegularReorg(t *testing.T) {
|
| 1461 |
genesis := state.Genesis{
|
| 1462 |
-
|
| 1463 |
}
|
| 1464 |
cfg := Config{
|
| 1465 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
@@ -1741,7 +1737,7 @@
|
|
| 1741 |
|
| 1742 |
func TestLatestSyncedBlockEmptyWithExtraReorg(t *testing.T) {
|
| 1743 |
genesis := state.Genesis{
|
| 1744 |
-
|
| 1745 |
}
|
| 1746 |
cfg := Config{
|
| 1747 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
@@ -2017,13 +2013,16 @@
|
|
| 2017 |
|
| 2018 |
func TestCallFromEmptyBlockAndReorg(t *testing.T) {
|
| 2019 |
genesis := state.Genesis{
|
| 2020 |
-
|
| 2021 |
}
|
| 2022 |
cfg := Config{
|
| 2023 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 2024 |
SyncChunkSize: 3,
|
| 2025 |
L1SynchronizationMode: SequentialMode,
|
| 2026 |
SyncBlockProtection: "latest",
|
|
|
|
|
|
|
|
|
|
| 2027 |
}
|
| 2028 |
|
| 2029 |
m := mocks{
|
|
@@ -2129,6 +2128,11 @@
|
|
| 2129 |
Return(ethHeader2bis, nil).
|
| 2130 |
Once()
|
| 2131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2132 |
ti := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
| 2133 |
|
| 2134 |
ethermanBlock0 := etherman.Block{
|
|
|
|
| 31 |
ETROG_MODE_FLAG = true
|
| 32 |
RETRIEVE_BATCH_FROM_DB_FLAG = true
|
| 33 |
RETRIEVE_BATCH_FROM_CACHE_FLAG = false
|
|
|
|
| 34 |
)
|
| 35 |
|
| 36 |
type mocks struct {
|
|
|
|
| 122 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 123 |
func TestForcedBatchEtrog(t *testing.T) {
|
| 124 |
genesis := state.Genesis{
|
| 125 |
+
RollupBlockNumber: uint64(123456),
|
| 126 |
}
|
| 127 |
cfg := Config{
|
| 128 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
|
|
| 169 |
On("GetForkIDByBatchNumber", mock.Anything).
|
| 170 |
Return(uint64(7), nil).
|
| 171 |
Maybe()
|
|
|
|
| 172 |
m.State.
|
| 173 |
On("GetLastBlock", ctx, m.DbTx).
|
| 174 |
Return(lastBlock0, nil).
|
|
|
|
| 224 |
Coinbase: common.HexToAddress("0x222"),
|
| 225 |
SequencerAddr: common.HexToAddress("0x00"),
|
| 226 |
TxHash: common.HexToHash("0x333"),
|
| 227 |
+
PolygonRollupBaseEtrogBatchData: &polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 228 |
Transactions: []byte{},
|
| 229 |
ForcedGlobalExitRoot: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32},
|
| 230 |
ForcedTimestamp: uint64(t.Unix()),
|
|
|
|
| 395 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 396 |
func TestSequenceForcedBatchIncaberry(t *testing.T) {
|
| 397 |
genesis := state.Genesis{
|
| 398 |
+
RollupBlockNumber: uint64(123456),
|
| 399 |
}
|
| 400 |
cfg := Config{
|
| 401 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
|
|
| 488 |
BatchNumber: uint64(2),
|
| 489 |
Coinbase: common.HexToAddress("0x222"),
|
| 490 |
TxHash: common.HexToHash("0x333"),
|
| 491 |
+
PolygonRollupBaseEtrogBatchData: polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 492 |
Transactions: []byte{},
|
| 493 |
ForcedGlobalExitRoot: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32},
|
| 494 |
ForcedTimestamp: 1000, //ForcedBatch
|
|
|
|
| 657 |
|
| 658 |
func setupGenericTest(t *testing.T) (*state.Genesis, *Config, *mocks) {
|
| 659 |
genesis := state.Genesis{
|
| 660 |
+
RollupBlockNumber: uint64(123456),
|
| 661 |
}
|
| 662 |
cfg := Config{
|
| 663 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
|
|
| 759 |
transactions := []types.TransactionOrHash{}
|
| 760 |
for nBlock := 0; nBlock < howManyBlocks; nBlock++ {
|
| 761 |
block := state.L2BlockRaw{
|
| 762 |
+
DeltaTimestamp: 123,
|
| 763 |
+
IndexL1InfoTree: 456,
|
| 764 |
+
Transactions: []state.L2TxRaw{},
|
|
|
|
|
|
|
| 765 |
}
|
| 766 |
for i := 0; i < howManyTx; i++ {
|
| 767 |
tx := createTransaction(uint64(i + 1))
|
|
|
|
| 921 |
|
| 922 |
func TestReorg(t *testing.T) {
|
| 923 |
genesis := state.Genesis{
|
| 924 |
+
RollupBlockNumber: uint64(0),
|
| 925 |
}
|
| 926 |
cfg := Config{
|
| 927 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
|
|
| 1241 |
|
| 1242 |
func TestLatestSyncedBlockEmpty(t *testing.T) {
|
| 1243 |
genesis := state.Genesis{
|
| 1244 |
+
RollupBlockNumber: uint64(0),
|
| 1245 |
}
|
| 1246 |
cfg := Config{
|
| 1247 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
|
|
| 1455 |
|
| 1456 |
func TestRegularReorg(t *testing.T) {
|
| 1457 |
genesis := state.Genesis{
|
| 1458 |
+
RollupBlockNumber: uint64(0),
|
| 1459 |
}
|
| 1460 |
cfg := Config{
|
| 1461 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
|
|
| 1737 |
|
| 1738 |
func TestLatestSyncedBlockEmptyWithExtraReorg(t *testing.T) {
|
| 1739 |
genesis := state.Genesis{
|
| 1740 |
+
RollupBlockNumber: uint64(0),
|
| 1741 |
}
|
| 1742 |
cfg := Config{
|
| 1743 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
|
|
|
| 2013 |
|
| 2014 |
func TestCallFromEmptyBlockAndReorg(t *testing.T) {
|
| 2015 |
genesis := state.Genesis{
|
| 2016 |
+
RollupBlockNumber: uint64(0),
|
| 2017 |
}
|
| 2018 |
cfg := Config{
|
| 2019 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 2020 |
SyncChunkSize: 3,
|
| 2021 |
L1SynchronizationMode: SequentialMode,
|
| 2022 |
SyncBlockProtection: "latest",
|
| 2023 |
+
L1BlockCheck: L1BlockCheckConfig{
|
| 2024 |
+
Enable: false,
|
| 2025 |
+
},
|
| 2026 |
}
|
| 2027 |
|
| 2028 |
m := mocks{
|
|
|
|
| 2128 |
Return(ethHeader2bis, nil).
|
| 2129 |
Once()
|
| 2130 |
|
| 2131 |
+
// m.Etherman.
|
| 2132 |
+
// On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 2133 |
+
// Return(ethBlock1, nil).
|
| 2134 |
+
// Once()
|
| 2135 |
+
|
| 2136 |
ti := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
| 2137 |
|
| 2138 |
ethermanBlock0 := etherman.Block{
|
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// SPDX-License-Identifier: MIT
|
| 2 |
+
pragma solidity >=0.7.0 <0.9.0;
|
| 3 |
+
|
| 4 |
+
contract customModExp {
|
| 5 |
+
bytes32 hashResult;
|
| 6 |
+
address retEcrecover;
|
| 7 |
+
bytes dataResult;
|
| 8 |
+
uint256 dataRes;
|
| 9 |
+
|
| 10 |
+
bytes32[10] arrayStorage;
|
| 11 |
+
|
| 12 |
+
function modExpGeneric(bytes memory input) public {
|
| 13 |
+
bytes32[10] memory output;
|
| 14 |
+
|
| 15 |
+
assembly {
|
| 16 |
+
let success := staticcall(gas(), 0x05, add(input, 32), mload(input), output, 0x140)
|
| 17 |
+
sstore(0x00, success)
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
for (uint i = 0; i < 10; i++) {
|
| 21 |
+
arrayStorage[i] = output[i];
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
|
@@ -2,7 +2,7 @@
|
|
| 2 |
networks:
|
| 3 |
default:
|
| 4 |
name: zkevm
|
| 5 |
-
|
| 6 |
services:
|
| 7 |
grafana:
|
| 8 |
container_name: grafana
|
|
@@ -453,9 +453,7 @@
|
|
| 453 |
|
| 454 |
zkevm-mock-l1-network:
|
| 455 |
container_name: zkevm-mock-l1-network
|
| 456 |
-
|
| 457 |
-
image: hermeznetwork/geth-zkevm-contracts:elderberry-fork.9-geth1.13.11
|
| 458 |
-
# image: hermeznetwork/geth-zkevm-contracts:v2.1.3-fork.8-geth1.12.0
|
| 459 |
ports:
|
| 460 |
- 8545:8545
|
| 461 |
- 8546:8546
|
|
@@ -515,15 +513,14 @@
|
|
| 515 |
|
| 516 |
zkevm-prover:
|
| 517 |
container_name: zkevm-prover
|
| 518 |
-
#image: hermeznetwork/zkevm-prover:v7.0.0-RC4
|
| 519 |
image: hermeznetwork/zkevm-prover:v6.0.0
|
| 520 |
ports:
|
| 521 |
- 50061:50061 # MT
|
| 522 |
- 50071:50071 # Executor
|
| 523 |
-
environment:
|
| 524 |
-
- EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1
|
| 525 |
volumes:
|
| 526 |
- ./config/test.prover.config.json:/usr/src/app/config.json
|
|
|
|
|
|
|
| 527 |
command: >
|
| 528 |
zkProver -c /usr/src/app/config.json
|
| 529 |
|
|
@@ -607,17 +604,16 @@
|
|
| 607 |
|
| 608 |
zkevm-permissionless-prover:
|
| 609 |
container_name: zkevm-permissionless-prover
|
| 610 |
-
#image: hermeznetwork/zkevm-prover:v7.0.0-RC4
|
| 611 |
image: hermeznetwork/zkevm-prover:v6.0.0
|
| 612 |
ports:
|
| 613 |
# - 50058:50058 # Prover
|
| 614 |
- 50059:50052 # Mock prover
|
| 615 |
- 50068:50061 # MT
|
| 616 |
- 50078:50071 # Executor
|
| 617 |
-
environment:
|
| 618 |
-
- EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1
|
| 619 |
volumes:
|
| 620 |
- ./config/test.permissionless.prover.config.json:/usr/src/app/config.json
|
|
|
|
|
|
|
| 621 |
command: >
|
| 622 |
zkProver -c /usr/src/app/config.json
|
| 623 |
|
|
@@ -636,7 +632,7 @@
|
|
| 636 |
zkevm-sh:
|
| 637 |
container_name: zkevm-sh
|
| 638 |
image: zkevm-node
|
| 639 |
-
stdin_open: true
|
| 640 |
tty: true
|
| 641 |
environment:
|
| 642 |
- ZKEVM_NODE_STATE_DB_HOST=zkevm-state-db
|
|
@@ -646,3 +642,51 @@
|
|
| 646 |
- ./config/test.genesis.config.json:/app/genesis.json
|
| 647 |
command:
|
| 648 |
- "/bin/sh"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
networks:
|
| 3 |
default:
|
| 4 |
name: zkevm
|
| 5 |
+
|
| 6 |
services:
|
| 7 |
grafana:
|
| 8 |
container_name: grafana
|
|
|
|
| 453 |
|
| 454 |
zkevm-mock-l1-network:
|
| 455 |
container_name: zkevm-mock-l1-network
|
| 456 |
+
image: 0xpolygon/cdk-validium-contracts:elderberry-fork.9-geth1.13.11
|
|
|
|
|
|
|
| 457 |
ports:
|
| 458 |
- 8545:8545
|
| 459 |
- 8546:8546
|
|
|
|
| 513 |
|
| 514 |
zkevm-prover:
|
| 515 |
container_name: zkevm-prover
|
|
|
|
| 516 |
image: hermeznetwork/zkevm-prover:v6.0.0
|
| 517 |
ports:
|
| 518 |
- 50061:50061 # MT
|
| 519 |
- 50071:50071 # Executor
|
|
|
|
|
|
|
| 520 |
volumes:
|
| 521 |
- ./config/test.prover.config.json:/usr/src/app/config.json
|
| 522 |
+
environment:
|
| 523 |
+
- EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1
|
| 524 |
command: >
|
| 525 |
zkProver -c /usr/src/app/config.json
|
| 526 |
|
|
|
|
| 604 |
|
| 605 |
zkevm-permissionless-prover:
|
| 606 |
container_name: zkevm-permissionless-prover
|
|
|
|
| 607 |
image: hermeznetwork/zkevm-prover:v6.0.0
|
| 608 |
ports:
|
| 609 |
# - 50058:50058 # Prover
|
| 610 |
- 50059:50052 # Mock prover
|
| 611 |
- 50068:50061 # MT
|
| 612 |
- 50078:50071 # Executor
|
|
|
|
|
|
|
| 613 |
volumes:
|
| 614 |
- ./config/test.permissionless.prover.config.json:/usr/src/app/config.json
|
| 615 |
+
environment:
|
| 616 |
+
- EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1
|
| 617 |
command: >
|
| 618 |
zkProver -c /usr/src/app/config.json
|
| 619 |
|
|
|
|
| 632 |
zkevm-sh:
|
| 633 |
container_name: zkevm-sh
|
| 634 |
image: zkevm-node
|
| 635 |
+
stdin_open: true
|
| 636 |
tty: true
|
| 637 |
environment:
|
| 638 |
- ZKEVM_NODE_STATE_DB_HOST=zkevm-state-db
|
|
|
|
| 642 |
- ./config/test.genesis.config.json:/app/genesis.json
|
| 643 |
command:
|
| 644 |
- "/bin/sh"
|
| 645 |
+
|
| 646 |
+
zkevm-node-forced-DAC:
|
| 647 |
+
container_name: zkevm-node-forced-DAC
|
| 648 |
+
image: zkevm-node
|
| 649 |
+
ports:
|
| 650 |
+
- 8125:8125
|
| 651 |
+
environment:
|
| 652 |
+
- ZKEVM_NODE_ISTRUSTEDSEQUENCER=false
|
| 653 |
+
- ZKEVM_NODE_STATEDB_USER=test_user
|
| 654 |
+
- ZKEVM_NODE_STATEDB_PASSWORD=test_password
|
| 655 |
+
- ZKEVM_NODE_STATEDB_NAME=state_db
|
| 656 |
+
- ZKEVM_NODE_STATEDB_HOST=zkevm-permissionless-db
|
| 657 |
+
- ZKEVM_NODE_POOL_DB_USER=test_user
|
| 658 |
+
- ZKEVM_NODE_POOL_DB_PASSWORD=test_password
|
| 659 |
+
- ZKEVM_NODE_POOL_DB_NAME=pool_db
|
| 660 |
+
- ZKEVM_NODE_POOL_DB_HOST=zkevm-permissionless-db
|
| 661 |
+
- ZKEVM_NODE_RPC_PORT=8125
|
| 662 |
+
- ZKEVM_NODE_RPC_SEQUENCERNODEURI=http://zkevm-node-json-rpc:8123
|
| 663 |
+
- ZKEVM_NODE_SYNCHRONIZER_TRUSTEDSEQUENCERURL=http://you-cant-touch-this:8123
|
| 664 |
+
- ZKEVM_NODE_MTCLIENT_URI=zkevm-permissionless-prover:50061
|
| 665 |
+
- ZKEVM_NODE_EXECUTOR_URI=zkevm-permissionless-prover:50071
|
| 666 |
+
volumes:
|
| 667 |
+
- ./config/test.node.config.toml:/app/config.toml
|
| 668 |
+
- ./config/test.genesis.config.json:/app/genesis.json
|
| 669 |
+
command:
|
| 670 |
+
- "/bin/sh"
|
| 671 |
+
- "-c"
|
| 672 |
+
- "/app/zkevm-node run --network custom --custom-network-file /app/genesis.json --cfg /app/config.toml --components \"rpc,synchronizer\""
|
| 673 |
+
|
| 674 |
+
zkevm-data-node-db:
|
| 675 |
+
container_name: zkevm-data-node-db
|
| 676 |
+
restart: unless-stopped
|
| 677 |
+
image: postgres
|
| 678 |
+
healthcheck:
|
| 679 |
+
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
| 680 |
+
interval: 10s
|
| 681 |
+
timeout: 5s
|
| 682 |
+
retries: 5
|
| 683 |
+
ports:
|
| 684 |
+
- 5444:5432
|
| 685 |
+
environment:
|
| 686 |
+
- POSTGRES_USER=committee_user
|
| 687 |
+
- POSTGRES_PASSWORD=committee_password
|
| 688 |
+
- POSTGRES_DB=committee_db
|
| 689 |
+
command:
|
| 690 |
+
- "postgres"
|
| 691 |
+
- "-N"
|
| 692 |
+
- "500"
|
|
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package e2e
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
+
"encoding/json"
|
| 7 |
+
"fmt"
|
| 8 |
+
"math/big"
|
| 9 |
+
"os"
|
| 10 |
+
"os/exec"
|
| 11 |
+
"sort"
|
| 12 |
+
"strconv"
|
| 13 |
+
"strings"
|
| 14 |
+
"testing"
|
| 15 |
+
"time"
|
| 16 |
+
|
| 17 |
+
"github.com/0xPolygon/cdk-data-availability/config"
|
| 18 |
+
cTypes "github.com/0xPolygon/cdk-data-availability/config/types"
|
| 19 |
+
"github.com/0xPolygon/cdk-data-availability/db"
|
| 20 |
+
"github.com/0xPolygon/cdk-data-availability/rpc"
|
| 21 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee"
|
| 22 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 23 |
+
"github.com/0xPolygonHermez/zkevm-node/test/operations"
|
| 24 |
+
"github.com/ethereum/go-ethereum"
|
| 25 |
+
eTypes "github.com/ethereum/go-ethereum/core/types"
|
| 26 |
+
|
| 27 |
+
"github.com/ethereum/go-ethereum/accounts/keystore"
|
| 28 |
+
"github.com/ethereum/go-ethereum/common"
|
| 29 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 30 |
+
"github.com/ethereum/go-ethereum/ethclient"
|
| 31 |
+
"github.com/stretchr/testify/assert"
|
| 32 |
+
"github.com/stretchr/testify/require"
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
func TestDataCommittee(t *testing.T) {
|
| 36 |
+
const (
|
| 37 |
+
nSignatures = 4
|
| 38 |
+
mMembers = 5
|
| 39 |
+
ksFile = "/tmp/pkey"
|
| 40 |
+
cfgFile = "/tmp/dacnodeconfigfile.json"
|
| 41 |
+
ksPass = "pass"
|
| 42 |
+
dacNodeContainer = "hermeznetwork/cdk-data-availability:v0.0.4"
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
// Setup
|
| 46 |
+
var err error
|
| 47 |
+
if testing.Short() {
|
| 48 |
+
t.Skip()
|
| 49 |
+
}
|
| 50 |
+
ctx := context.Background()
|
| 51 |
+
defer func() {
|
| 52 |
+
require.NoError(t, operations.Teardown())
|
| 53 |
+
}()
|
| 54 |
+
err = operations.Teardown()
|
| 55 |
+
require.NoError(t, err)
|
| 56 |
+
opsCfg := operations.GetDefaultOperationsConfig()
|
| 57 |
+
opsCfg.State.MaxCumulativeGasUsed = 80000000000
|
| 58 |
+
opsman, err := operations.NewManager(ctx, opsCfg)
|
| 59 |
+
require.NoError(t, err)
|
| 60 |
+
defer func() {
|
| 61 |
+
require.NoError(t, opsman.StopDACDB())
|
| 62 |
+
}()
|
| 63 |
+
err = opsman.Setup()
|
| 64 |
+
require.NoError(t, err)
|
| 65 |
+
require.NoError(t, opsman.StartDACDB())
|
| 66 |
+
time.Sleep(5 * time.Second)
|
| 67 |
+
authL2, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL2ChainID)
|
| 68 |
+
require.NoError(t, err)
|
| 69 |
+
authL1, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL1ChainID)
|
| 70 |
+
require.NoError(t, err)
|
| 71 |
+
clientL2, err := ethclient.Dial(operations.DefaultL2NetworkURL)
|
| 72 |
+
require.NoError(t, err)
|
| 73 |
+
clientL1, err := ethclient.Dial(operations.DefaultL1NetworkURL)
|
| 74 |
+
require.NoError(t, err)
|
| 75 |
+
dacSC, err := polygondatacommittee.NewPolygondatacommittee(
|
| 76 |
+
common.HexToAddress(operations.DefaultL1DataCommitteeContract),
|
| 77 |
+
clientL1,
|
| 78 |
+
)
|
| 79 |
+
require.NoError(t, err)
|
| 80 |
+
|
| 81 |
+
// Register committee with N / M signatures
|
| 82 |
+
membs := members{}
|
| 83 |
+
addrsBytes := []byte{}
|
| 84 |
+
urls := []string{}
|
| 85 |
+
for i := 0; i < mMembers; i++ {
|
| 86 |
+
pk, err := crypto.GenerateKey()
|
| 87 |
+
require.NoError(t, err)
|
| 88 |
+
membs = append(membs, member{
|
| 89 |
+
addr: crypto.PubkeyToAddress(pk.PublicKey),
|
| 90 |
+
pk: pk,
|
| 91 |
+
url: fmt.Sprintf("http://cdk-data-availability-%d:420%d", i, i),
|
| 92 |
+
i: i,
|
| 93 |
+
})
|
| 94 |
+
}
|
| 95 |
+
sort.Sort(membs)
|
| 96 |
+
for _, m := range membs {
|
| 97 |
+
addrsBytes = append(addrsBytes, m.addr.Bytes()...)
|
| 98 |
+
urls = append(urls, m.url)
|
| 99 |
+
}
|
| 100 |
+
tx, err := dacSC.SetupCommittee(authL1, big.NewInt(nSignatures), urls, addrsBytes)
|
| 101 |
+
for _, m := range membs {
|
| 102 |
+
fmt.Println(m.addr)
|
| 103 |
+
}
|
| 104 |
+
require.NoError(t, err)
|
| 105 |
+
err = operations.WaitTxToBeMined(ctx, clientL1, tx, operations.DefaultTimeoutTxToBeMined)
|
| 106 |
+
require.NoError(t, err)
|
| 107 |
+
|
| 108 |
+
// Spin up M DAC nodes
|
| 109 |
+
dacNodeConfig := config.Config{
|
| 110 |
+
L1: config.L1Config{
|
| 111 |
+
RpcURL: "http://zkevm-mock-l1-network:8545",
|
| 112 |
+
WsURL: "ws://zkevm-mock-l1-network:8546",
|
| 113 |
+
PolygonValidiumAddress: operations.DefaultL1ZkEVMSmartContract,
|
| 114 |
+
DataCommitteeAddress: operations.DefaultL1DataCommitteeContract,
|
| 115 |
+
Timeout: cTypes.Duration{Duration: time.Second},
|
| 116 |
+
RetryPeriod: cTypes.Duration{Duration: time.Second},
|
| 117 |
+
},
|
| 118 |
+
PrivateKey: cTypes.KeystoreFileConfig{
|
| 119 |
+
Path: ksFile,
|
| 120 |
+
Password: ksPass,
|
| 121 |
+
},
|
| 122 |
+
DB: db.Config{
|
| 123 |
+
Name: "committee_db",
|
| 124 |
+
User: "committee_user",
|
| 125 |
+
Password: "committee_password",
|
| 126 |
+
Host: "zkevm-data-node-db",
|
| 127 |
+
Port: "5432",
|
| 128 |
+
EnableLog: false,
|
| 129 |
+
MaxConns: 10,
|
| 130 |
+
},
|
| 131 |
+
RPC: rpc.Config{
|
| 132 |
+
Host: "0.0.0.0",
|
| 133 |
+
MaxRequestsPerIPAndSecond: 100,
|
| 134 |
+
},
|
| 135 |
+
}
|
| 136 |
+
defer func() {
|
| 137 |
+
// Remove tmp files
|
| 138 |
+
assert.NoError(t,
|
| 139 |
+
exec.Command("rm", cfgFile).Run(),
|
| 140 |
+
)
|
| 141 |
+
assert.NoError(t,
|
| 142 |
+
exec.Command("rmdir", ksFile+"_").Run(),
|
| 143 |
+
)
|
| 144 |
+
assert.NoError(t,
|
| 145 |
+
exec.Command("rm", ksFile).Run(),
|
| 146 |
+
)
|
| 147 |
+
// Stop DAC nodes
|
| 148 |
+
for i := 0; i < mMembers; i++ {
|
| 149 |
+
assert.NoError(t, exec.Command(
|
| 150 |
+
"docker", "kill", "cdk-data-availability-"+strconv.Itoa(i),
|
| 151 |
+
).Run())
|
| 152 |
+
assert.NoError(t, exec.Command(
|
| 153 |
+
"docker", "rm", "cdk-data-availability-"+strconv.Itoa(i),
|
| 154 |
+
).Run())
|
| 155 |
+
}
|
| 156 |
+
// Stop permissionless node
|
| 157 |
+
require.NoError(t, opsman.StopPermissionlessNodeForcedToSYncThroughDAC())
|
| 158 |
+
}()
|
| 159 |
+
// Start permissionless node
|
| 160 |
+
require.NoError(t, opsman.StartPermissionlessNodeForcedToSYncThroughDAC())
|
| 161 |
+
// Star DAC nodes
|
| 162 |
+
for _, m := range membs {
|
| 163 |
+
// Set correct port
|
| 164 |
+
port := 4200 + m.i
|
| 165 |
+
dacNodeConfig.RPC.Port = port
|
| 166 |
+
// Write config file
|
| 167 |
+
file, err := json.MarshalIndent(dacNodeConfig, "", " ")
|
| 168 |
+
require.NoError(t, err)
|
| 169 |
+
err = os.WriteFile(cfgFile, file, 0644)
|
| 170 |
+
require.NoError(t, err)
|
| 171 |
+
// Write private key keystore file
|
| 172 |
+
err = createKeyStore(m.pk, ksFile, ksPass)
|
| 173 |
+
require.NoError(t, err)
|
| 174 |
+
// Run DAC node
|
| 175 |
+
cmd := exec.Command(
|
| 176 |
+
"docker", "run", "-d",
|
| 177 |
+
"--name", "cdk-data-availability-"+strconv.Itoa(m.i),
|
| 178 |
+
"-v", cfgFile+":/app/config.json",
|
| 179 |
+
"-v", ksFile+":"+ksFile,
|
| 180 |
+
"--network", "zkevm",
|
| 181 |
+
dacNodeContainer,
|
| 182 |
+
"/bin/sh", "-c",
|
| 183 |
+
"/app/cdk-data-availability run --cfg /app/config.json",
|
| 184 |
+
)
|
| 185 |
+
out, err := cmd.CombinedOutput()
|
| 186 |
+
require.NoError(t, err, string(out))
|
| 187 |
+
log.Infof("DAC node %d started", m.i)
|
| 188 |
+
time.Sleep(time.Second * 5)
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
// Send txs
|
| 192 |
+
nTxs := 10
|
| 193 |
+
amount := big.NewInt(10000)
|
| 194 |
+
toAddress := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8")
|
| 195 |
+
_, err = clientL2.BalanceAt(ctx, authL2.From, nil)
|
| 196 |
+
require.NoError(t, err)
|
| 197 |
+
_, err = clientL2.PendingNonceAt(ctx, authL2.From)
|
| 198 |
+
require.NoError(t, err)
|
| 199 |
+
|
| 200 |
+
gasLimit, err := clientL2.EstimateGas(ctx, ethereum.CallMsg{From: authL2.From, To: &toAddress, Value: amount})
|
| 201 |
+
require.NoError(t, err)
|
| 202 |
+
|
| 203 |
+
gasPrice, err := clientL2.SuggestGasPrice(ctx)
|
| 204 |
+
require.NoError(t, err)
|
| 205 |
+
|
| 206 |
+
nonce, err := clientL2.PendingNonceAt(ctx, authL2.From)
|
| 207 |
+
require.NoError(t, err)
|
| 208 |
+
|
| 209 |
+
txs := make([]*eTypes.Transaction, 0, nTxs)
|
| 210 |
+
for i := 0; i < nTxs; i++ {
|
| 211 |
+
tx := eTypes.NewTransaction(nonce+uint64(i), toAddress, amount, gasLimit, gasPrice, nil)
|
| 212 |
+
log.Infof("generating tx %d / %d: %s", i+1, nTxs, tx.Hash().Hex())
|
| 213 |
+
txs = append(txs, tx)
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
// Wait for verification
|
| 217 |
+
_, err = operations.ApplyL2Txs(ctx, txs, authL2, clientL2, operations.VerifiedConfirmationLevel)
|
| 218 |
+
require.NoError(t, err)
|
| 219 |
+
|
| 220 |
+
// Assert that he permissionless node is fully synced (through the DAC)
|
| 221 |
+
time.Sleep(30 * time.Second) // Give some time for the permissionless node to get synced
|
| 222 |
+
clientL2Permissionless, err := ethclient.Dial(operations.PermissionlessL2NetworkURL)
|
| 223 |
+
require.NoError(t, err)
|
| 224 |
+
expectedBlock, err := clientL2.BlockByNumber(ctx, nil)
|
| 225 |
+
require.NoError(t, err)
|
| 226 |
+
actualBlock, err := clientL2Permissionless.BlockByNumber(ctx, nil)
|
| 227 |
+
require.NoError(t, err)
|
| 228 |
+
// je, err := expectedBlock.Header().MarshalJSON()
|
| 229 |
+
// require.NoError(t, err)
|
| 230 |
+
// log.Info(string(je))
|
| 231 |
+
// ja, err := actualBlock.Header().MarshalJSON()
|
| 232 |
+
// require.NoError(t, err)
|
| 233 |
+
// log.Info(string(ja))
|
| 234 |
+
// require.Equal(t, string(je), string(ja))
|
| 235 |
+
require.Equal(t, expectedBlock.Root().Hex(), actualBlock.Root().Hex())
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
type member struct {
|
| 239 |
+
addr common.Address
|
| 240 |
+
pk *ecdsa.PrivateKey
|
| 241 |
+
url string
|
| 242 |
+
i int
|
| 243 |
+
}
|
| 244 |
+
type members []member
|
| 245 |
+
|
| 246 |
+
func (s members) Len() int { return len(s) }
|
| 247 |
+
func (s members) Less(i, j int) bool {
|
| 248 |
+
return strings.ToUpper(s[i].addr.Hex()) < strings.ToUpper(s[j].addr.Hex())
|
| 249 |
+
}
|
| 250 |
+
func (s members) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
| 251 |
+
|
| 252 |
+
func createKeyStore(pk *ecdsa.PrivateKey, outputDir, password string) error {
|
| 253 |
+
ks := keystore.NewKeyStore(outputDir+"_", keystore.StandardScryptN, keystore.StandardScryptP)
|
| 254 |
+
_, err := ks.ImportECDSA(pk, password)
|
| 255 |
+
if err != nil {
|
| 256 |
+
return err
|
| 257 |
+
}
|
| 258 |
+
fileNameB, err := exec.Command("ls", outputDir+"_/").CombinedOutput()
|
| 259 |
+
fileName := strings.TrimSuffix(string(fileNameB), "\n")
|
| 260 |
+
if err != nil {
|
| 261 |
+
fmt.Println(fileName)
|
| 262 |
+
return err
|
| 263 |
+
}
|
| 264 |
+
out, err := exec.Command("mv", outputDir+"_/"+fileName, outputDir).CombinedOutput()
|
| 265 |
+
if err != nil {
|
| 266 |
+
fmt.Println(string(out))
|
| 267 |
+
return err
|
| 268 |
+
}
|
| 269 |
+
return nil
|
| 270 |
+
}
|
|
@@ -36,7 +36,7 @@
|
|
| 36 |
authSequencer *bind.TransactOpts
|
| 37 |
authForcedBatch *bind.TransactOpts
|
| 38 |
zkEvmAddr common.Address
|
| 39 |
-
zkEvm *
|
| 40 |
}
|
| 41 |
|
| 42 |
type l2Stuff struct {
|
|
@@ -186,7 +186,7 @@
|
|
| 186 |
require.NoError(t, err)
|
| 187 |
|
| 188 |
zkEvmAddr := common.HexToAddress(operations.DefaultL1ZkEVMSmartContract)
|
| 189 |
-
zkEvm, err :=
|
| 190 |
require.NoError(t, err)
|
| 191 |
return &l1Stuff{ethClient: ethClient, authSequencer: authSequencer, authForcedBatch: authForcedBatch, zkEvmAddr: zkEvmAddr, zkEvm: zkEvm}
|
| 192 |
}
|
|
@@ -196,7 +196,7 @@
|
|
| 196 |
require.NoError(t, err)
|
| 197 |
genesisConfig, err := config.LoadGenesisFromJSONString(genesisFileAsStr)
|
| 198 |
require.NoError(t, err)
|
| 199 |
-
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.
|
| 200 |
err = opsman.Setup()
|
| 201 |
require.NoError(t, err)
|
| 202 |
time.Sleep(5 * time.Second)
|
|
@@ -216,7 +216,7 @@
|
|
| 216 |
log.Info("Number of forceBatches in the smc: ", num)
|
| 217 |
|
| 218 |
rollupManagerAddr := common.HexToAddress(operations.DefaultL1RollupManagerSmartContract)
|
| 219 |
-
rollupManager, err :=
|
| 220 |
require.NoError(t, err)
|
| 221 |
|
| 222 |
// Get tip
|
|
@@ -226,7 +226,7 @@
|
|
| 226 |
managerAddress, err := l1.zkEvm.GlobalExitRootManager(&bind.CallOpts{Pending: false})
|
| 227 |
require.NoError(t, err)
|
| 228 |
|
| 229 |
-
manager, err :=
|
| 230 |
require.NoError(t, err)
|
| 231 |
|
| 232 |
rootInContract, err := manager.GetLastGlobalExitRoot(&bind.CallOpts{Pending: false})
|
|
@@ -299,7 +299,7 @@
|
|
| 299 |
return forcedBatch, nil
|
| 300 |
}
|
| 301 |
|
| 302 |
-
func findForcedBatchInL1Logs(ctx context.Context, t *testing.T, fromBlock *big.Int, l1 *l1Stuff) (*
|
| 303 |
query := ethereum.FilterQuery{
|
| 304 |
FromBlock: fromBlock,
|
| 305 |
Addresses: []common.Address{l1.zkEvmAddr},
|
|
|
|
| 36 |
authSequencer *bind.TransactOpts
|
| 37 |
authForcedBatch *bind.TransactOpts
|
| 38 |
zkEvmAddr common.Address
|
| 39 |
+
zkEvm *polygonzkevm.Polygonzkevm
|
| 40 |
}
|
| 41 |
|
| 42 |
type l2Stuff struct {
|
|
|
|
| 186 |
require.NoError(t, err)
|
| 187 |
|
| 188 |
zkEvmAddr := common.HexToAddress(operations.DefaultL1ZkEVMSmartContract)
|
| 189 |
+
zkEvm, err := polygonzkevm.NewPolygonzkevm(zkEvmAddr, ethClient)
|
| 190 |
require.NoError(t, err)
|
| 191 |
return &l1Stuff{ethClient: ethClient, authSequencer: authSequencer, authForcedBatch: authForcedBatch, zkEvmAddr: zkEvmAddr, zkEvm: zkEvm}
|
| 192 |
}
|
|
|
|
| 196 |
require.NoError(t, err)
|
| 197 |
genesisConfig, err := config.LoadGenesisFromJSONString(genesisFileAsStr)
|
| 198 |
require.NoError(t, err)
|
| 199 |
+
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.RollupBlockNumber, forkID6))
|
| 200 |
err = opsman.Setup()
|
| 201 |
require.NoError(t, err)
|
| 202 |
time.Sleep(5 * time.Second)
|
|
|
|
| 216 |
log.Info("Number of forceBatches in the smc: ", num)
|
| 217 |
|
| 218 |
rollupManagerAddr := common.HexToAddress(operations.DefaultL1RollupManagerSmartContract)
|
| 219 |
+
rollupManager, err := polygonrollupmanager.NewPolygonrollupmanager(rollupManagerAddr, l1.ethClient)
|
| 220 |
require.NoError(t, err)
|
| 221 |
|
| 222 |
// Get tip
|
|
|
|
| 226 |
managerAddress, err := l1.zkEvm.GlobalExitRootManager(&bind.CallOpts{Pending: false})
|
| 227 |
require.NoError(t, err)
|
| 228 |
|
| 229 |
+
manager, err := polygonzkevmglobalexitroot.NewPolygonzkevmglobalexitroot(managerAddress, l1.ethClient)
|
| 230 |
require.NoError(t, err)
|
| 231 |
|
| 232 |
rootInContract, err := manager.GetLastGlobalExitRoot(&bind.CallOpts{Pending: false})
|
|
|
|
| 299 |
return forcedBatch, nil
|
| 300 |
}
|
| 301 |
|
| 302 |
+
func findForcedBatchInL1Logs(ctx context.Context, t *testing.T, fromBlock *big.Int, l1 *l1Stuff) (*polygonzkevm.PolygonzkevmForceBatch, *types.Log, error) {
|
| 303 |
query := ethereum.FilterQuery{
|
| 304 |
FromBlock: fromBlock,
|
| 305 |
Addresses: []common.Address{l1.zkEvmAddr},
|
|
@@ -63,8 +63,8 @@
|
|
| 63 |
log.Info("# Setting Genesis #")
|
| 64 |
log.Info("###################")
|
| 65 |
genesisActions := vectors.GenerateGenesisActions(testCase.Genesis)
|
| 66 |
-
require.NoError(t, opsman.SetGenesis(genesisConfig.Genesis.
|
| 67 |
-
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.
|
| 68 |
actualOldStateRoot, err := opsman.State().GetLastStateRoot(ctx, nil)
|
| 69 |
require.NoError(t, err)
|
| 70 |
require.NoError(t, opsman.Setup())
|
|
|
|
| 63 |
log.Info("# Setting Genesis #")
|
| 64 |
log.Info("###################")
|
| 65 |
genesisActions := vectors.GenerateGenesisActions(testCase.Genesis)
|
| 66 |
+
require.NoError(t, opsman.SetGenesis(genesisConfig.Genesis.RollupBlockNumber, genesisActions))
|
| 67 |
+
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.RollupBlockNumber, forkID6))
|
| 68 |
actualOldStateRoot, err := opsman.State().GetLastStateRoot(ctx, nil)
|
| 69 |
require.NoError(t, err)
|
| 70 |
require.NoError(t, opsman.Setup())
|
|
@@ -71,7 +71,6 @@
|
|
| 71 |
}
|
| 72 |
ctx := context.Background()
|
| 73 |
setup()
|
| 74 |
-
|
| 75 |
defer teardown()
|
| 76 |
for _, network := range networks {
|
| 77 |
// test newBlockFilter creation
|
|
@@ -88,9 +87,9 @@
|
|
| 88 |
|
| 89 |
// test newFilter creation with block range and block hash
|
| 90 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 91 |
-
"
|
| 92 |
-
"
|
| 93 |
-
"
|
| 94 |
})
|
| 95 |
require.NoError(t, err)
|
| 96 |
require.NotNil(t, response.Error)
|
|
@@ -99,11 +98,11 @@
|
|
| 99 |
|
| 100 |
// test newFilter creation with block hash
|
| 101 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 102 |
-
"
|
| 103 |
-
"
|
| 104 |
common.HexToAddress("0x2"),
|
| 105 |
},
|
| 106 |
-
"
|
| 107 |
{common.HexToHash("0x3")},
|
| 108 |
},
|
| 109 |
})
|
|
@@ -118,12 +117,12 @@
|
|
| 118 |
|
| 119 |
// test newFilter creation with block range
|
| 120 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 121 |
-
"
|
| 122 |
-
"
|
| 123 |
-
"
|
| 124 |
common.HexToAddress("0x2"),
|
| 125 |
},
|
| 126 |
-
"
|
| 127 |
{common.HexToHash("0x3")},
|
| 128 |
},
|
| 129 |
})
|
|
@@ -211,7 +210,7 @@
|
|
| 211 |
require.NoError(t, err)
|
| 212 |
|
| 213 |
assert.NotEqual(t, blockBeforeFilterHash.String(), blockFilterChanges[0].String())
|
| 214 |
-
assert.Equal(t, blockAfterFilterHash.String(), blockFilterChanges[len(blockFilterChanges)-1].String()
|
| 215 |
|
| 216 |
// test getFilterChanges for a logFilter ID
|
| 217 |
// create a SC to emit some logs
|
|
@@ -221,7 +220,7 @@
|
|
| 221 |
require.NoError(t, err)
|
| 222 |
|
| 223 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 224 |
-
"
|
| 225 |
})
|
| 226 |
require.NoError(t, err)
|
| 227 |
require.Nil(t, response.Error)
|
|
@@ -277,7 +276,7 @@
|
|
| 277 |
require.NoError(t, err)
|
| 278 |
|
| 279 |
assert.Equal(t, 30, len(logs))
|
| 280 |
-
assert.Equal(t, 20, len(logFilterChanges)
|
| 281 |
}
|
| 282 |
}
|
| 283 |
|
|
|
|
| 71 |
}
|
| 72 |
ctx := context.Background()
|
| 73 |
setup()
|
|
|
|
| 74 |
defer teardown()
|
| 75 |
for _, network := range networks {
|
| 76 |
// test newBlockFilter creation
|
|
|
|
| 87 |
|
| 88 |
// test newFilter creation with block range and block hash
|
| 89 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 90 |
+
"BlockHash": common.HexToHash("0x1"),
|
| 91 |
+
"FromBlock": "0x1",
|
| 92 |
+
"ToBlock": "0x2",
|
| 93 |
})
|
| 94 |
require.NoError(t, err)
|
| 95 |
require.NotNil(t, response.Error)
|
|
|
|
| 98 |
|
| 99 |
// test newFilter creation with block hash
|
| 100 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 101 |
+
"BlockHash": common.HexToHash("0x1"),
|
| 102 |
+
"Addresses": []common.Address{
|
| 103 |
common.HexToAddress("0x2"),
|
| 104 |
},
|
| 105 |
+
"Topics": [][]common.Hash{
|
| 106 |
{common.HexToHash("0x3")},
|
| 107 |
},
|
| 108 |
})
|
|
|
|
| 117 |
|
| 118 |
// test newFilter creation with block range
|
| 119 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 120 |
+
"FromBlock": "0x1",
|
| 121 |
+
"ToBlock": "0x2",
|
| 122 |
+
"Addresses": []common.Address{
|
| 123 |
common.HexToAddress("0x2"),
|
| 124 |
},
|
| 125 |
+
"Topics": [][]common.Hash{
|
| 126 |
{common.HexToHash("0x3")},
|
| 127 |
},
|
| 128 |
})
|
|
|
|
| 210 |
require.NoError(t, err)
|
| 211 |
|
| 212 |
assert.NotEqual(t, blockBeforeFilterHash.String(), blockFilterChanges[0].String())
|
| 213 |
+
assert.Equal(t, blockAfterFilterHash.String(), blockFilterChanges[len(blockFilterChanges)-1].String())
|
| 214 |
|
| 215 |
// test getFilterChanges for a logFilter ID
|
| 216 |
// create a SC to emit some logs
|
|
|
|
| 220 |
require.NoError(t, err)
|
| 221 |
|
| 222 |
response, err = client.JSONRPCCall(network.URL, "eth_newFilter", map[string]interface{}{
|
| 223 |
+
"Addresses": []common.Address{scAddr},
|
| 224 |
})
|
| 225 |
require.NoError(t, err)
|
| 226 |
require.Nil(t, response.Error)
|
|
|
|
| 276 |
require.NoError(t, err)
|
| 277 |
|
| 278 |
assert.Equal(t, 30, len(logs))
|
| 279 |
+
assert.Equal(t, 20, len(logFilterChanges))
|
| 280 |
}
|
| 281 |
}
|
| 282 |
|
|
@@ -141,11 +141,11 @@
|
|
| 141 |
|
| 142 |
// Create smc client
|
| 143 |
zkEvmAddr := common.HexToAddress(operations.DefaultL1ZkEVMSmartContract)
|
| 144 |
-
zkEvm, err :=
|
| 145 |
require.NoError(t, err)
|
| 146 |
|
| 147 |
rollupManagerAddr := common.HexToAddress(operations.DefaultL1RollupManagerSmartContract)
|
| 148 |
-
rollupManager, err :=
|
| 149 |
require.NoError(t, err)
|
| 150 |
|
| 151 |
auth, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL1ChainID)
|
|
|
|
| 141 |
|
| 142 |
// Create smc client
|
| 143 |
zkEvmAddr := common.HexToAddress(operations.DefaultL1ZkEVMSmartContract)
|
| 144 |
+
zkEvm, err := polygonzkevm.NewPolygonzkevm(zkEvmAddr, ethClient)
|
| 145 |
require.NoError(t, err)
|
| 146 |
|
| 147 |
rollupManagerAddr := common.HexToAddress(operations.DefaultL1RollupManagerSmartContract)
|
| 148 |
+
rollupManager, err := polygonrollupmanager.NewPolygonrollupmanager(rollupManagerAddr, ethClient)
|
| 149 |
require.NoError(t, err)
|
| 150 |
|
| 151 |
auth, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL1ChainID)
|
|
@@ -59,7 +59,7 @@
|
|
| 59 |
for _, gacc := range testCase.GenesisAccounts {
|
| 60 |
genesisAccounts[gacc.Address] = gacc.Balance.Int
|
| 61 |
}
|
| 62 |
-
require.NoError(t, opsman.SetGenesisAccountsBalance(genesisConfig.Genesis.
|
| 63 |
|
| 64 |
// Check initial root
|
| 65 |
require.NoError(t, opsman.CheckVirtualRoot(testCase.ExpectedOldRoot))
|
|
|
|
| 59 |
for _, gacc := range testCase.GenesisAccounts {
|
| 60 |
genesisAccounts[gacc.Address] = gacc.Balance.Int
|
| 61 |
}
|
| 62 |
+
require.NoError(t, opsman.SetGenesisAccountsBalance(genesisConfig.Genesis.RollupBlockNumber, genesisAccounts))
|
| 63 |
|
| 64 |
// Check initial root
|
| 65 |
require.NoError(t, opsman.CheckVirtualRoot(testCase.ExpectedOldRoot))
|
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
DOCKERCOMPOSE := docker compose -f docker-compose.yml
|
| 2 |
DOCKERCOMPOSEAPPSEQ := zkevm-sequencer
|
| 3 |
DOCKERCOMPOSEAPPSEQV1TOV2 := zkevm-sequencer-v1tov2
|
| 4 |
DOCKERCOMPOSEAPPSEQSENDER := zkevm-sequence-sender
|
|
@@ -26,6 +26,7 @@
|
|
| 26 |
DOCKERCOMPOSEZKPROVER := zkevm-prover
|
| 27 |
DOCKERCOMPOSEPERMISSIONLESSDB := zkevm-permissionless-db
|
| 28 |
DOCKERCOMPOSEPERMISSIONLESSNODE := zkevm-permissionless-node
|
|
|
|
| 29 |
DOCKERCOMPOSEPERMISSIONLESSZKPROVER := zkevm-permissionless-prover
|
| 30 |
DOCKERCOMPOSENODEAPPROVE := zkevm-approve
|
| 31 |
DOCKERCOMPOSENODEAPPROVEV1TOV2 := zkevm-approve-v1tov2
|
|
@@ -62,6 +63,7 @@
|
|
| 62 |
|
| 63 |
RUNPERMISSIONLESSDB := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 64 |
RUNPERMISSIONLESSNODE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
|
|
|
| 65 |
RUNPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 66 |
|
| 67 |
RUNAPPROVE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSENODEAPPROVE)
|
|
@@ -101,6 +103,7 @@
|
|
| 101 |
|
| 102 |
STOPPERMISSIONLESSDB := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSDB) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 103 |
STOPPERMISSIONLESSNODE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
|
|
|
| 104 |
STOPPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 105 |
|
| 106 |
STOPAPPROVE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSENODEAPPROVE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSENODEAPPROVE)
|
|
@@ -110,6 +113,9 @@
|
|
| 110 |
|
| 111 |
STOP := $(DOCKERCOMPOSE) down --remove-orphans
|
| 112 |
|
|
|
|
|
|
|
|
|
|
| 113 |
.PHONY: test-full-non-e2e
|
| 114 |
test-full-non-e2e: stop ## Runs non-e2e tests checking race conditions
|
| 115 |
$(RUNSTATEDB)
|
|
@@ -122,22 +128,7 @@
|
|
| 122 |
sleep 15
|
| 123 |
docker ps -a
|
| 124 |
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 125 |
-
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -short -race -p 1 -covermode=atomic -coverprofile=../coverage.out -coverpkg ./... -timeout
|
| 126 |
-
|
| 127 |
-
.PHONY: test-full-non-e2e-sonar
|
| 128 |
-
test-full-non-e2e-sonar: stop ## Runs non-e2e tests checking race conditions
|
| 129 |
-
$(RUNSTATEDB)
|
| 130 |
-
$(RUNPOOLDB)
|
| 131 |
-
$(RUNEVENTDB)
|
| 132 |
-
sleep 2
|
| 133 |
-
$(RUNZKPROVER)
|
| 134 |
-
sleep 7
|
| 135 |
-
$(RUNL1NETWORK)
|
| 136 |
-
sleep 15
|
| 137 |
-
docker ps -a
|
| 138 |
-
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 139 |
-
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -short -race -p 1 -covermode=atomic -coverprofile=../coverage.out -coverpkg ./... -timeout 200s ../... -json > ../report.json
|
| 140 |
-
|
| 141 |
|
| 142 |
.PHONY: test-e2e-group-1
|
| 143 |
test-e2e-group-1: stop ## Runs group 1 e2e tests checking race conditions
|
|
@@ -263,6 +254,17 @@
|
|
| 263 |
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 264 |
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 2000s ../ci/e2e-group11/...
|
| 265 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
.PHONY: benchmark-sequencer-eth-transfers
|
| 267 |
benchmark-sequencer-eth-transfers: stop
|
| 268 |
$(RUNL1NETWORK)
|
|
@@ -379,7 +381,7 @@
|
|
| 379 |
$(STOPZKPROVER)
|
| 380 |
|
| 381 |
.PHONY: run-l1-explorer
|
| 382 |
-
run-l1-explorer: ## Runs L1 blockscan explorer
|
| 383 |
$(RUNEXPLORERL1DB)
|
| 384 |
$(RUNEXPLORERL1)
|
| 385 |
|
|
@@ -449,7 +451,7 @@
|
|
| 449 |
.PHONY: stop-seqsender-v1tov2
|
| 450 |
stop-seqsender-v1tov2: ## stops the sequencer sender
|
| 451 |
$(STOPV1TOV2SEQUENCESENDER)
|
| 452 |
-
|
| 453 |
.PHONY: run-sync
|
| 454 |
run-sync: ## runs the synchronizer
|
| 455 |
$(RUNSYNC)
|
|
@@ -513,7 +515,7 @@
|
|
| 513 |
.PHONY: stop-eth-tx-manager-v1tov2
|
| 514 |
stop-eth-tx-manager-v1tov2: ## Stops the eth tx manager service
|
| 515 |
$(STOPV1TOV2ETHTXMANAGER)
|
| 516 |
-
|
| 517 |
.PHONY: run-agg
|
| 518 |
run-agg: ## Runs the aggregator service
|
| 519 |
$(RUNAGGREGATOR)
|
|
@@ -555,7 +557,7 @@
|
|
| 555 |
$(RUNPERMISSIONLESSDB)
|
| 556 |
sleep 3
|
| 557 |
$(RUNPERMISSIONLESSZKPROVER)
|
| 558 |
-
|
| 559 |
|
| 560 |
PHONY: stop-permissionless-dependencies
|
| 561 |
stop-permissionless-dependencies: ## Stop the permissionless dependencies (db + prover) without the node
|
|
@@ -644,7 +646,7 @@
|
|
| 644 |
go run ./scripts/init_network/main.go .
|
| 645 |
|
| 646 |
.PHONY: show-logs
|
| 647 |
-
show-logs: ## Show logs for running docker
|
| 648 |
$(DOCKERCOMPOSE) logs
|
| 649 |
|
| 650 |
.PHONY: deploy-sc
|
|
@@ -700,10 +702,12 @@
|
|
| 700 |
.PHONY: generate-mocks-synchronizer
|
| 701 |
generate-mocks-synchronizer: ## Generates mocks for synchronizer , using mockery tool
|
| 702 |
## mocks for synchronizer
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
|
|
|
|
|
|
| 707 |
for i in l1RollupProducerInterface l1RollupConsumerInterface worker synchronizerProcessBlockRangeInterface workersInterface L1ParallelEthermanInterface; do \
|
| 708 |
camelcase=$$(echo $$i | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g' | tr '[:upper:]' '[:lower:]') ; \
|
| 709 |
echo $$camelcase ; \
|
|
@@ -712,13 +716,13 @@
|
|
| 712 |
|
| 713 |
rm -Rf ../synchronizer/l2_sync/l2_sync_etrog/mocks
|
| 714 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_sync_etrog --output ../synchronizer/l2_sync/l2_sync_etrog/mocks --outpkg mock_l2_sync_etrog ${COMMON_MOCKERY_PARAMS}
|
| 715 |
-
|
| 716 |
rm -Rf ../synchronizer/l2_sync/l2_shared/mocks
|
| 717 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_shared --output ../synchronizer/l2_sync/l2_shared/mocks --outpkg mock_l2_shared ${COMMON_MOCKERY_PARAMS}
|
| 718 |
-
|
| 719 |
rm -Rf ../synchronizer/common/syncinterfaces/mocks
|
| 720 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/common/syncinterfaces --output ../synchronizer/common/syncinterfaces/mocks --outpkg mock_syncinterfaces ${COMMON_MOCKERY_PARAMS}
|
| 721 |
-
|
| 722 |
rm -Rf ../synchronizer/actions/elderberry/mocks
|
| 723 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/actions/elderberry --output ../synchronizer/actions/elderberry/mocks --outpkg mock_elderberry ${COMMON_MOCKERY_PARAMS}
|
| 724 |
|
|
@@ -728,27 +732,24 @@
|
|
| 728 |
|
| 729 |
|
| 730 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../synchronizer/mocks --structname=DbTxMock --filename=mock_dbtx.go ${COMMON_MOCKERY_PARAMS}
|
| 731 |
-
|
| 732 |
-
.PHONY: generate-mocks-etherman
|
| 733 |
generate-mocks-etherman: ## Generates mocks for etherman , using mockery tool
|
| 734 |
## mocks for etherman
|
| 735 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=GasPricer --srcpkg=github.com/ethereum/go-ethereum --output=../etherman --outpkg=etherman --structname=etherscanMock --filename=mock_etherscan.go
|
| 736 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=GasPricer --srcpkg=github.com/ethereum/go-ethereum --output=../etherman --outpkg=etherman --structname=ethGasStationMock --filename=mock_ethgasstation.go
|
| 737 |
-
|
| 738 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ChainReader --srcpkg=github.com/ethereum/go-ethereum --output=../etherman --outpkg=etherman --structname=ChainReaderMock --filename=mock_chainreader.go ${COMMON_MOCKERY_PARAMS}
|
| 739 |
|
|
|
|
|
|
|
| 740 |
|
| 741 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=
|
| 742 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=
|
| 743 |
|
| 744 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=
|
| 745 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=
|
| 746 |
|
| 747 |
-
rm -Rf ../etherman/mockseth
|
| 748 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../etherman/ --output ../etherman/mockseth --outpkg mockseth ${COMMON_MOCKERY_PARAMS}
|
| 749 |
-
|
| 750 |
|
| 751 |
-
.PHONY: generate-mocks-aggregator
|
| 752 |
generate-mocks-aggregator: ## Generates mocks for aggregator , using mockery tool
|
| 753 |
## mocks for the aggregator tests
|
| 754 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateInterface --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=StateMock --filename=mock_state.go
|
|
@@ -758,7 +759,7 @@
|
|
| 758 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=aggregatorTxProfitabilityChecker --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=ProfitabilityCheckerMock --filename=mock_profitabilitychecker.go
|
| 759 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../aggregator/mocks --outpkg=mocks --structname=DbTxMock --filename=mock_dbtx.go
|
| 760 |
|
| 761 |
-
.PHONY: generate-mocks-state
|
| 762 |
generate-mocks-state: ## Generates mocks for state , using mockery tool
|
| 763 |
## mocks for the aggregator tests
|
| 764 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=storage --dir=../state --output=../state/mocks --outpkg=mocks --structname=StorageMock --filename=mock_storage.go --disable-version-string --with-expecter
|
|
@@ -770,6 +771,27 @@
|
|
| 770 |
run-benchmarks: run-db ## Runs benchmars
|
| 771 |
go test -bench=. ./state/tree
|
| 772 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 773 |
.PHONY: compile-scs
|
| 774 |
compile-scs: ## Compiles smart contracts, configuration in test/contracts/index.yaml
|
| 775 |
go run ./scripts/cmd... compilesc --input ./contracts
|
|
|
|
| 1 |
+
DOCKERCOMPOSE := docker compose -f docker-compose.yml
|
| 2 |
DOCKERCOMPOSEAPPSEQ := zkevm-sequencer
|
| 3 |
DOCKERCOMPOSEAPPSEQV1TOV2 := zkevm-sequencer-v1tov2
|
| 4 |
DOCKERCOMPOSEAPPSEQSENDER := zkevm-sequence-sender
|
|
|
|
| 26 |
DOCKERCOMPOSEZKPROVER := zkevm-prover
|
| 27 |
DOCKERCOMPOSEPERMISSIONLESSDB := zkevm-permissionless-db
|
| 28 |
DOCKERCOMPOSEPERMISSIONLESSNODE := zkevm-permissionless-node
|
| 29 |
+
DOCKERCOMPOSEPERMISSIONLESSNODEDAC := zkevm-node-forced-DAC
|
| 30 |
DOCKERCOMPOSEPERMISSIONLESSZKPROVER := zkevm-permissionless-prover
|
| 31 |
DOCKERCOMPOSENODEAPPROVE := zkevm-approve
|
| 32 |
DOCKERCOMPOSENODEAPPROVEV1TOV2 := zkevm-approve-v1tov2
|
|
|
|
| 63 |
|
| 64 |
RUNPERMISSIONLESSDB := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 65 |
RUNPERMISSIONLESSNODE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
| 66 |
+
RUNPERMISSIONLESSNODEDAC := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC)
|
| 67 |
RUNPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 68 |
|
| 69 |
RUNAPPROVE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSENODEAPPROVE)
|
|
|
|
| 103 |
|
| 104 |
STOPPERMISSIONLESSDB := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSDB) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 105 |
STOPPERMISSIONLESSNODE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
| 106 |
+
STOPPERMISSIONLESSNODEDAC := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC)
|
| 107 |
STOPPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 108 |
|
| 109 |
STOPAPPROVE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSENODEAPPROVE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSENODEAPPROVE)
|
|
|
|
| 113 |
|
| 114 |
STOP := $(DOCKERCOMPOSE) down --remove-orphans
|
| 115 |
|
| 116 |
+
RUNDACDB := docker-compose up -d zkevm-data-node-db
|
| 117 |
+
STOPDACDB := docker-compose stop zkevm-data-node-db && docker-compose rm -f zkevm-data-node-db
|
| 118 |
+
|
| 119 |
.PHONY: test-full-non-e2e
|
| 120 |
test-full-non-e2e: stop ## Runs non-e2e tests checking race conditions
|
| 121 |
$(RUNSTATEDB)
|
|
|
|
| 128 |
sleep 15
|
| 129 |
docker ps -a
|
| 130 |
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 131 |
+
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -short -race -p 1 -covermode=atomic -coverprofile=../coverage.out -coverpkg ./... -timeout 70s ../...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
|
| 133 |
.PHONY: test-e2e-group-1
|
| 134 |
test-e2e-group-1: stop ## Runs group 1 e2e tests checking race conditions
|
|
|
|
| 254 |
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 255 |
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 2000s ../ci/e2e-group11/...
|
| 256 |
|
| 257 |
+
.PHONY: test-e2e-group-cdk-validium-1
|
| 258 |
+
test-e2e-group-cdk-validium-1: stop ## Runs cdk-validium-1 e2e tests checking race conditions
|
| 259 |
+
$(RUNSTATEDB)
|
| 260 |
+
$(RUNPOOLDB)
|
| 261 |
+
$(RUNEVENTDB)
|
| 262 |
+
sleep 5
|
| 263 |
+
$(RUNZKPROVER)
|
| 264 |
+
docker ps -a
|
| 265 |
+
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 266 |
+
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -race -v -p 1 -timeout 2000s ../ci/e2e-group-cdk-validium-1/...
|
| 267 |
+
|
| 268 |
.PHONY: benchmark-sequencer-eth-transfers
|
| 269 |
benchmark-sequencer-eth-transfers: stop
|
| 270 |
$(RUNL1NETWORK)
|
|
|
|
| 381 |
$(STOPZKPROVER)
|
| 382 |
|
| 383 |
.PHONY: run-l1-explorer
|
| 384 |
+
run-l1-explorer: ## Runs L1 blockscan explorer
|
| 385 |
$(RUNEXPLORERL1DB)
|
| 386 |
$(RUNEXPLORERL1)
|
| 387 |
|
|
|
|
| 451 |
.PHONY: stop-seqsender-v1tov2
|
| 452 |
stop-seqsender-v1tov2: ## stops the sequencer sender
|
| 453 |
$(STOPV1TOV2SEQUENCESENDER)
|
| 454 |
+
|
| 455 |
.PHONY: run-sync
|
| 456 |
run-sync: ## runs the synchronizer
|
| 457 |
$(RUNSYNC)
|
|
|
|
| 515 |
.PHONY: stop-eth-tx-manager-v1tov2
|
| 516 |
stop-eth-tx-manager-v1tov2: ## Stops the eth tx manager service
|
| 517 |
$(STOPV1TOV2ETHTXMANAGER)
|
| 518 |
+
|
| 519 |
.PHONY: run-agg
|
| 520 |
run-agg: ## Runs the aggregator service
|
| 521 |
$(RUNAGGREGATOR)
|
|
|
|
| 557 |
$(RUNPERMISSIONLESSDB)
|
| 558 |
sleep 3
|
| 559 |
$(RUNPERMISSIONLESSZKPROVER)
|
| 560 |
+
|
| 561 |
|
| 562 |
PHONY: stop-permissionless-dependencies
|
| 563 |
stop-permissionless-dependencies: ## Stop the permissionless dependencies (db + prover) without the node
|
|
|
|
| 646 |
go run ./scripts/init_network/main.go .
|
| 647 |
|
| 648 |
.PHONY: show-logs
|
| 649 |
+
show-logs: ## Show logs for running docker
|
| 650 |
$(DOCKERCOMPOSE) logs
|
| 651 |
|
| 652 |
.PHONY: deploy-sc
|
|
|
|
| 702 |
.PHONY: generate-mocks-synchronizer
|
| 703 |
generate-mocks-synchronizer: ## Generates mocks for synchronizer , using mockery tool
|
| 704 |
## mocks for synchronizer
|
| 705 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthermanFullInterface --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=ethermanMock --filename=mock_etherman.go ${COMMON_MOCKERY_PARAMS}
|
| 706 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=StateFullInterface --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=StateMock --filename=mock_state.go ${COMMON_MOCKERY_PARAMS}
|
| 707 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthTxManager --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=ethTxManagerMock --filename=mock_ethtxmanager.go ${COMMON_MOCKERY_PARAMS}
|
| 708 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=PoolInterface --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=poolMock --filename=mock_pool.go ${COMMON_MOCKERY_PARAMS}
|
| 709 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Factory --srcpkg=github.com/0xPolygon/cdk-data-availability/client --output=../synchronizer --outpkg=synchronizer --structname=dataCommitteeClientFactoryMock --filename=mock_datacommitteeclientfactory.go ${COMMON_MOCKERY_PARAMS}
|
| 710 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Client --srcpkg=github.com/0xPolygon/cdk-data-availability/client --output=../synchronizer --outpkg=synchronizer --structname=dataCommitteeClientMock --filename=mock_datacommitteeclient.go ${COMMON_MOCKERY_PARAMS}
|
| 711 |
for i in l1RollupProducerInterface l1RollupConsumerInterface worker synchronizerProcessBlockRangeInterface workersInterface L1ParallelEthermanInterface; do \
|
| 712 |
camelcase=$$(echo $$i | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g' | tr '[:upper:]' '[:lower:]') ; \
|
| 713 |
echo $$camelcase ; \
|
|
|
|
| 716 |
|
| 717 |
rm -Rf ../synchronizer/l2_sync/l2_sync_etrog/mocks
|
| 718 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_sync_etrog --output ../synchronizer/l2_sync/l2_sync_etrog/mocks --outpkg mock_l2_sync_etrog ${COMMON_MOCKERY_PARAMS}
|
| 719 |
+
|
| 720 |
rm -Rf ../synchronizer/l2_sync/l2_shared/mocks
|
| 721 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_shared --output ../synchronizer/l2_sync/l2_shared/mocks --outpkg mock_l2_shared ${COMMON_MOCKERY_PARAMS}
|
| 722 |
+
|
| 723 |
rm -Rf ../synchronizer/common/syncinterfaces/mocks
|
| 724 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/common/syncinterfaces --output ../synchronizer/common/syncinterfaces/mocks --outpkg mock_syncinterfaces ${COMMON_MOCKERY_PARAMS}
|
| 725 |
+
|
| 726 |
rm -Rf ../synchronizer/actions/elderberry/mocks
|
| 727 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/actions/elderberry --output ../synchronizer/actions/elderberry/mocks --outpkg mock_elderberry ${COMMON_MOCKERY_PARAMS}
|
| 728 |
|
|
|
|
| 732 |
|
| 733 |
|
| 734 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../synchronizer/mocks --structname=DbTxMock --filename=mock_dbtx.go ${COMMON_MOCKERY_PARAMS}
|
| 735 |
+
|
| 736 |
+
.PHONY: generate-mocks-etherman
|
| 737 |
generate-mocks-etherman: ## Generates mocks for etherman , using mockery tool
|
| 738 |
## mocks for etherman
|
| 739 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=GasPricer --srcpkg=github.com/ethereum/go-ethereum --output=../etherman --outpkg=etherman --structname=etherscanMock --filename=mock_etherscan.go
|
| 740 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=GasPricer --srcpkg=github.com/ethereum/go-ethereum --output=../etherman --outpkg=etherman --structname=ethGasStationMock --filename=mock_ethgasstation.go
|
|
|
|
|
|
|
| 741 |
|
| 742 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ethermanInterface --dir=../ethtxmanager --output=../ethtxmanager --outpkg=ethtxmanager --structname=ethermanMock --filename=mock_etherman_test.go
|
| 743 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateInterface --dir=../ethtxmanager --output=../ethtxmanager --outpkg=ethtxmanager --structname=stateMock --filename=mock_state_test.go
|
| 744 |
|
| 745 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=poolInterface --dir=../gasprice --output=../gasprice --outpkg=gasprice --structname=poolMock --filename=mock_pool.go
|
| 746 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ethermanInterface --dir=../gasprice --output=../gasprice --outpkg=gasprice --structname=ethermanMock --filename=mock_etherman.go
|
| 747 |
|
| 748 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=dataAvailabilityProvider --dir=../etherman --output=../etherman --outpkg=etherman --structname=daMock --filename=mock_da.go
|
| 749 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateProvider --dir=../etherman --output=../etherman --outpkg=etherman --structname=stateMock --filename=mock_state.go
|
| 750 |
|
|
|
|
|
|
|
|
|
|
| 751 |
|
| 752 |
+
.PHONY: generate-mocks-aggregator
|
| 753 |
generate-mocks-aggregator: ## Generates mocks for aggregator , using mockery tool
|
| 754 |
## mocks for the aggregator tests
|
| 755 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateInterface --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=StateMock --filename=mock_state.go
|
|
|
|
| 759 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=aggregatorTxProfitabilityChecker --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=ProfitabilityCheckerMock --filename=mock_profitabilitychecker.go
|
| 760 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../aggregator/mocks --outpkg=mocks --structname=DbTxMock --filename=mock_dbtx.go
|
| 761 |
|
| 762 |
+
.PHONY: generate-mocks-state
|
| 763 |
generate-mocks-state: ## Generates mocks for state , using mockery tool
|
| 764 |
## mocks for the aggregator tests
|
| 765 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=storage --dir=../state --output=../state/mocks --outpkg=mocks --structname=StorageMock --filename=mock_storage.go --disable-version-string --with-expecter
|
|
|
|
| 771 |
run-benchmarks: run-db ## Runs benchmars
|
| 772 |
go test -bench=. ./state/tree
|
| 773 |
|
| 774 |
+
.PHONY: run-dac-db
|
| 775 |
+
run-dac-db: ## Suns the DAC DB
|
| 776 |
+
$(RUNDACDB)
|
| 777 |
+
|
| 778 |
+
.PHONY: stop-dac-db
|
| 779 |
+
stop-dac-db: ## Stops the DAC DB
|
| 780 |
+
$(STOPDACDB)
|
| 781 |
+
|
| 782 |
+
.PHONY: run-permissionless-dac
|
| 783 |
+
run-permissionless-dac: ## Runs a permissionless node that is forced to sync through DAC
|
| 784 |
+
$(RUNPERMISSIONLESSDB)
|
| 785 |
+
sleep 1
|
| 786 |
+
$(RUNPERMISSIONLESSZKPROVER)
|
| 787 |
+
$(RUNPERMISSIONLESSNODEDAC)
|
| 788 |
+
|
| 789 |
+
.PHONY: stop-permissionless-dac
|
| 790 |
+
stop-permissionless-dac: ## Stops the permissionless node that is forced to sync through DAC
|
| 791 |
+
$(STOPPERMISSIONLESSNODEDAC)
|
| 792 |
+
$(STOPPERMISSIONLESSZKPROVER)
|
| 793 |
+
$(STOPPERMISSIONLESSDB)
|
| 794 |
+
|
| 795 |
.PHONY: compile-scs
|
| 796 |
compile-scs: ## Compiles smart contracts, configuration in test/contracts/index.yaml
|
| 797 |
go run ./scripts/cmd... compilesc --input ./contracts
|
|
@@ -46,6 +46,7 @@
|
|
| 46 |
DefaultL1ZkEVMSmartContract = "0x8dAF17A20c9DBA35f005b6324F493785D239719d"
|
| 47 |
DefaultL1RollupManagerSmartContract = "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"
|
| 48 |
DefaultL1PolSmartContract = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
|
|
|
|
| 49 |
DefaultL1NetworkURL = "http://localhost:8545"
|
| 50 |
DefaultL1NetworkWebSocketURL = "ws://localhost:8546"
|
| 51 |
DefaultL1ChainID uint64 = 1337
|
|
@@ -263,7 +264,6 @@
|
|
| 263 |
if confirmationLevel == PoolConfirmationLevel {
|
| 264 |
return nil, nil
|
| 265 |
}
|
| 266 |
-
|
| 267 |
l2BlockNumbers := make([]*big.Int, 0, len(sentTxs))
|
| 268 |
for _, tx := range sentTxs {
|
| 269 |
// check transaction nonce against transaction reported L2 block number
|
|
@@ -503,11 +503,7 @@
|
|
| 503 |
if err != nil {
|
| 504 |
panic(err)
|
| 505 |
}
|
| 506 |
-
|
| 507 |
-
if err != nil {
|
| 508 |
-
panic(err)
|
| 509 |
-
}
|
| 510 |
-
st := state.NewState(stateCfg, stateDb, executorClient, stateTree, eventLog, mt, mtr)
|
| 511 |
return st, nil
|
| 512 |
}
|
| 513 |
|
|
@@ -666,3 +662,23 @@
|
|
| 666 |
panic(err)
|
| 667 |
}
|
| 668 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
DefaultL1ZkEVMSmartContract = "0x8dAF17A20c9DBA35f005b6324F493785D239719d"
|
| 47 |
DefaultL1RollupManagerSmartContract = "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"
|
| 48 |
DefaultL1PolSmartContract = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
|
| 49 |
+
DefaultL1DataCommitteeContract = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE"
|
| 50 |
DefaultL1NetworkURL = "http://localhost:8545"
|
| 51 |
DefaultL1NetworkWebSocketURL = "ws://localhost:8546"
|
| 52 |
DefaultL1ChainID uint64 = 1337
|
|
|
|
| 264 |
if confirmationLevel == PoolConfirmationLevel {
|
| 265 |
return nil, nil
|
| 266 |
}
|
|
|
|
| 267 |
l2BlockNumbers := make([]*big.Int, 0, len(sentTxs))
|
| 268 |
for _, tx := range sentTxs {
|
| 269 |
// check transaction nonce against transaction reported L2 block number
|
|
|
|
| 503 |
if err != nil {
|
| 504 |
panic(err)
|
| 505 |
}
|
| 506 |
+
st := state.NewState(stateCfg, stateDb, executorClient, stateTree, eventLog, mt)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 507 |
return st, nil
|
| 508 |
}
|
| 509 |
|
|
|
|
| 662 |
panic(err)
|
| 663 |
}
|
| 664 |
}
|
| 665 |
+
|
| 666 |
+
// StartDACDB starts the data availability node DB
|
| 667 |
+
func (m *Manager) StartDACDB() error {
|
| 668 |
+
return StartComponent("dac-db", func() (bool, error) { return true, nil })
|
| 669 |
+
}
|
| 670 |
+
|
| 671 |
+
// StopDACDB stops the data availability node DB
|
| 672 |
+
func (m *Manager) StopDACDB() error {
|
| 673 |
+
return StopComponent("dac-db")
|
| 674 |
+
}
|
| 675 |
+
|
| 676 |
+
// StartPermissionlessNodeForcedToSYncThroughDAC starts a permissionless node that is froced to sync through the DAC
|
| 677 |
+
func (m *Manager) StartPermissionlessNodeForcedToSYncThroughDAC() error {
|
| 678 |
+
return StartComponent("permissionless-dac", func() (bool, error) { return true, nil })
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
// StopPermissionlessNodeForcedToSYncThroughDAC stops the permissionless node that is froced to sync through the DAC
|
| 682 |
+
func (m *Manager) StopPermissionlessNodeForcedToSYncThroughDAC() error {
|
| 683 |
+
return StopComponent("permissionless-dac")
|
| 684 |
+
}
|
|
@@ -111,7 +111,7 @@
|
|
| 111 |
return err
|
| 112 |
}
|
| 113 |
|
| 114 |
-
ethMan, err := etherman.NewClient(cfg.Etherman, cfg.NetworkConfig.L1Config)
|
| 115 |
if err != nil {
|
| 116 |
return err
|
| 117 |
}
|
|
@@ -183,7 +183,7 @@
|
|
| 183 |
// send to L1
|
| 184 |
firstSequence := seqs[0]
|
| 185 |
lastSequence := seqs[len(seqs)-1]
|
| 186 |
-
to, data, err := ethMan.BuildSequenceBatchesTxData(auth.From, seqs, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber, auth.From)
|
| 187 |
if err != nil {
|
| 188 |
return err
|
| 189 |
}
|
|
@@ -289,7 +289,7 @@
|
|
| 289 |
switch vLog.Topics[0] {
|
| 290 |
case etherman.SequencedBatchesSigHash():
|
| 291 |
if vLog.TxHash == tx.Hash() { // ignore other txs happening on L1
|
| 292 |
-
sb, err := ethMan.
|
| 293 |
if err != nil {
|
| 294 |
return err
|
| 295 |
}
|
|
@@ -302,7 +302,7 @@
|
|
| 302 |
}
|
| 303 |
}
|
| 304 |
case etherman.TrustedVerifyBatchesSigHash():
|
| 305 |
-
vb, err := ethMan.
|
| 306 |
if err != nil {
|
| 307 |
return err
|
| 308 |
}
|
|
|
|
| 111 |
return err
|
| 112 |
}
|
| 113 |
|
| 114 |
+
ethMan, err := etherman.NewClient(cfg.Etherman, cfg.NetworkConfig.L1Config, nil, nil)
|
| 115 |
if err != nil {
|
| 116 |
return err
|
| 117 |
}
|
|
|
|
| 183 |
// send to L1
|
| 184 |
firstSequence := seqs[0]
|
| 185 |
lastSequence := seqs[len(seqs)-1]
|
| 186 |
+
to, data, err := ethMan.BuildSequenceBatchesTxData(auth.From, seqs, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber, auth.From, nil)
|
| 187 |
if err != nil {
|
| 188 |
return err
|
| 189 |
}
|
|
|
|
| 289 |
switch vLog.Topics[0] {
|
| 290 |
case etherman.SequencedBatchesSigHash():
|
| 291 |
if vLog.TxHash == tx.Hash() { // ignore other txs happening on L1
|
| 292 |
+
sb, err := ethMan.ZkEVM.ParseSequenceBatches(vLog)
|
| 293 |
if err != nil {
|
| 294 |
return err
|
| 295 |
}
|
|
|
|
| 302 |
}
|
| 303 |
}
|
| 304 |
case etherman.TrustedVerifyBatchesSigHash():
|
| 305 |
+
vb, err := ethMan.ZkEVM.ParseVerifyBatches(vLog)
|
| 306 |
if err != nil {
|
| 307 |
return err
|
| 308 |
}
|
|
@@ -132,6 +132,12 @@
|
|
| 132 |
log.Debugf("Sending TX to transfer ETH")
|
| 133 |
to := common.HexToAddress(receiverAddr)
|
| 134 |
tx = ethTransfer(ctx, client, auth, to, transferAmount, nil)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
err = operations.WaitTxToBeMined(ctx, client, tx, txTimeout)
|
| 136 |
chkErr(err)
|
| 137 |
fmt.Println()
|
|
|
|
| 132 |
log.Debugf("Sending TX to transfer ETH")
|
| 133 |
to := common.HexToAddress(receiverAddr)
|
| 134 |
tx = ethTransfer(ctx, client, auth, to, transferAmount, nil)
|
| 135 |
+
fmt.Println()
|
| 136 |
+
|
| 137 |
+
// Invalid ETH Transfer
|
| 138 |
+
log.Debugf("Sending Invalid TX to transfer ETH")
|
| 139 |
+
nonce := tx.Nonce() + 1
|
| 140 |
+
ethTransfer(ctx, client, auth, to, transferAmount, &nonce)
|
| 141 |
err = operations.WaitTxToBeMined(ctx, client, tx, txTimeout)
|
| 142 |
chkErr(err)
|
| 143 |
fmt.Println()
|
|
@@ -1,124 +0,0 @@
|
|
| 1 |
-
package main
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"errors"
|
| 6 |
-
"fmt"
|
| 7 |
-
"math/big"
|
| 8 |
-
"sync"
|
| 9 |
-
"time"
|
| 10 |
-
|
| 11 |
-
"github.com/ethereum/go-ethereum"
|
| 12 |
-
"github.com/ethereum/go-ethereum/core/types"
|
| 13 |
-
"github.com/ethereum/go-ethereum/ethclient"
|
| 14 |
-
)
|
| 15 |
-
|
| 16 |
-
// add here the url of the nodes you want to check
|
| 17 |
-
// against the trusted node
|
| 18 |
-
var networkURLsToCheck = []string{
|
| 19 |
-
// "https://add.your.node.url.here",
|
| 20 |
-
// "https://add.your.node.url.here",
|
| 21 |
-
// "https://add.your.node.url.here",
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
// set the from and to block numbers you want to verify
|
| 25 |
-
const fromBlockNumber uint64 = 10
|
| 26 |
-
const toBlockNumber uint64 = 20
|
| 27 |
-
|
| 28 |
-
// pick the correct trusted Node URL depending on the network you are testing
|
| 29 |
-
|
| 30 |
-
// mainnet
|
| 31 |
-
const trustedNodeURL = "https://zkevm-rpc.com"
|
| 32 |
-
|
| 33 |
-
// cardona
|
| 34 |
-
// const trustedNodeURL = "https://rpc.cardona.zkevm-rpc.com/"
|
| 35 |
-
|
| 36 |
-
func main() {
|
| 37 |
-
fmt.Printf("connecting to network: %v ...", trustedNodeURL)
|
| 38 |
-
trustedNodeClient, err := ethclient.Dial(trustedNodeURL)
|
| 39 |
-
chkErr(err)
|
| 40 |
-
fmt.Print("connected")
|
| 41 |
-
fmt.Println()
|
| 42 |
-
|
| 43 |
-
networkClients := map[string]*ethclient.Client{}
|
| 44 |
-
for _, networkURL := range networkURLsToCheck {
|
| 45 |
-
fmt.Printf("connecting to network: %v ...", networkURL)
|
| 46 |
-
client, err := ethclient.Dial(networkURL)
|
| 47 |
-
chkErr(err)
|
| 48 |
-
networkClients[networkURL] = client
|
| 49 |
-
fmt.Print("connected")
|
| 50 |
-
fmt.Println()
|
| 51 |
-
}
|
| 52 |
-
|
| 53 |
-
for blockNumberU64 := fromBlockNumber; blockNumberU64 <= toBlockNumber; blockNumberU64++ {
|
| 54 |
-
ctx := context.Background()
|
| 55 |
-
blockNumber := big.NewInt(0).SetUint64(blockNumberU64)
|
| 56 |
-
fmt.Println()
|
| 57 |
-
fmt.Println("block to verify: ", blockNumberU64)
|
| 58 |
-
|
| 59 |
-
// load blocks from trusted node
|
| 60 |
-
trustedNodeBlockHeader, err := trustedNodeClient.HeaderByNumber(ctx, blockNumber)
|
| 61 |
-
chkErr(err)
|
| 62 |
-
const logPattern = "block: %v hash: %v parentHash: %v network: %v\n"
|
| 63 |
-
trustedNodeBlockHash := trustedNodeBlockHeader.Hash().String()
|
| 64 |
-
trustedNodeParentBlockHash := trustedNodeBlockHeader.ParentHash.String()
|
| 65 |
-
|
| 66 |
-
// load blocks from networks to verify
|
| 67 |
-
blocks := sync.Map{}
|
| 68 |
-
wg := sync.WaitGroup{}
|
| 69 |
-
wg.Add(len(networkURLsToCheck))
|
| 70 |
-
for _, networkURL := range networkURLsToCheck {
|
| 71 |
-
go func(networkURL string) {
|
| 72 |
-
defer wg.Done()
|
| 73 |
-
c := networkClients[networkURL]
|
| 74 |
-
|
| 75 |
-
blockHeader, err := c.HeaderByNumber(ctx, blockNumber)
|
| 76 |
-
if errors.Is(err, ethereum.NotFound) {
|
| 77 |
-
return
|
| 78 |
-
} else {
|
| 79 |
-
chkErr(err)
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
blocks.Store(networkURL, blockHeader)
|
| 83 |
-
}(networkURL)
|
| 84 |
-
}
|
| 85 |
-
wg.Wait()
|
| 86 |
-
|
| 87 |
-
failed := false
|
| 88 |
-
blocks.Range(func(networkURLValue, blockValue any) bool {
|
| 89 |
-
networkURL, block := networkURLValue.(string), blockValue.(*types.Header)
|
| 90 |
-
|
| 91 |
-
// when block is not found
|
| 92 |
-
if block == nil {
|
| 93 |
-
fmt.Printf(logPattern, blockNumberU64, "NOT FOUND", "NOT FOUND", networkURL)
|
| 94 |
-
return true
|
| 95 |
-
}
|
| 96 |
-
|
| 97 |
-
blockHash := block.Hash().String()
|
| 98 |
-
parentBlockHash := block.ParentHash.String()
|
| 99 |
-
|
| 100 |
-
if trustedNodeBlockHash != blockHash || trustedNodeParentBlockHash != parentBlockHash {
|
| 101 |
-
failed = true
|
| 102 |
-
fmt.Printf(logPattern, blockNumberU64, trustedNodeBlockHash, trustedNodeParentBlockHash, trustedNodeURL)
|
| 103 |
-
fmt.Printf(logPattern, blockNumberU64, blockHash, parentBlockHash, networkURL)
|
| 104 |
-
fmt.Printf("ERROR block information mismatch for network: %v\n", networkURL)
|
| 105 |
-
} else {
|
| 106 |
-
fmt.Printf("%v: OK\n", networkURL)
|
| 107 |
-
}
|
| 108 |
-
|
| 109 |
-
return true
|
| 110 |
-
})
|
| 111 |
-
if failed {
|
| 112 |
-
panic("block information mismatch")
|
| 113 |
-
}
|
| 114 |
-
|
| 115 |
-
// avoid getting blocked by request rate limit
|
| 116 |
-
time.Sleep(time.Second)
|
| 117 |
-
}
|
| 118 |
-
}
|
| 119 |
-
|
| 120 |
-
func chkErr(err error) {
|
| 121 |
-
if err != nil {
|
| 122 |
-
panic(err)
|
| 123 |
-
}
|
| 124 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,188 +0,0 @@
|
|
| 1 |
-
package main
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"encoding/json"
|
| 5 |
-
"fmt"
|
| 6 |
-
|
| 7 |
-
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 8 |
-
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/client"
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 10 |
-
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
-
"github.com/ethereum/go-ethereum/common"
|
| 12 |
-
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
| 13 |
-
"github.com/ethereum/go-ethereum/trie"
|
| 14 |
-
)
|
| 15 |
-
|
| 16 |
-
const (
|
| 17 |
-
networkURL = "https://zkevm-rpc.com"
|
| 18 |
-
startBlockNumber uint64 = 10
|
| 19 |
-
endBlockNumber uint64 = 20
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
func main() {
|
| 23 |
-
for blockNumber := startBlockNumber; blockNumber <= endBlockNumber; blockNumber++ {
|
| 24 |
-
printfLn("getting block: %v", blockNumber)
|
| 25 |
-
blockResponse, err := client.JSONRPCCall(networkURL, "eth_getBlockByNumber", hex.EncodeUint64(blockNumber), true)
|
| 26 |
-
chkErr(err)
|
| 27 |
-
chkRespErr(blockResponse.Error)
|
| 28 |
-
|
| 29 |
-
rawBlock := map[string]interface{}{}
|
| 30 |
-
err = json.Unmarshal(blockResponse.Result, &rawBlock)
|
| 31 |
-
chkErr(err)
|
| 32 |
-
|
| 33 |
-
// create header
|
| 34 |
-
rawBlockHash := rawBlock["hash"].(string)
|
| 35 |
-
number := hex.DecodeBig(rawBlock["number"].(string))
|
| 36 |
-
parentHash := common.HexToHash(rawBlock["parentHash"].(string))
|
| 37 |
-
coinbase := common.HexToAddress(rawBlock["miner"].(string))
|
| 38 |
-
root := common.HexToHash(rawBlock["stateRoot"].(string))
|
| 39 |
-
gasUsed := hex.DecodeUint64(rawBlock["gasUsed"].(string))
|
| 40 |
-
gasLimit := hex.DecodeUint64(rawBlock["gasLimit"].(string))
|
| 41 |
-
timeStamp := hex.DecodeUint64(rawBlock["timestamp"].(string))
|
| 42 |
-
|
| 43 |
-
header := ðTypes.Header{
|
| 44 |
-
Number: number, ParentHash: parentHash, Coinbase: coinbase,
|
| 45 |
-
Root: root, GasUsed: gasUsed, GasLimit: gasLimit, Time: timeStamp,
|
| 46 |
-
}
|
| 47 |
-
|
| 48 |
-
// create txs and receipts
|
| 49 |
-
rawTransactions := rawBlock["transactions"].([]interface{})
|
| 50 |
-
txs := make([]*ethTypes.Transaction, 0, len(rawTransactions))
|
| 51 |
-
receipts := make([]*ethTypes.Receipt, 0, len(rawTransactions))
|
| 52 |
-
for i, rawTransaction := range rawTransactions {
|
| 53 |
-
if i == 1 {
|
| 54 |
-
continue
|
| 55 |
-
}
|
| 56 |
-
rawTransactionMap := rawTransaction.(map[string]interface{})
|
| 57 |
-
|
| 58 |
-
nonce := hex.DecodeUint64(rawTransactionMap["nonce"].(string))
|
| 59 |
-
gasPrice := hex.DecodeBig(rawTransactionMap["gasPrice"].(string))
|
| 60 |
-
gas := hex.DecodeUint64(rawTransactionMap["gas"].(string))
|
| 61 |
-
var to *common.Address
|
| 62 |
-
if rawTransactionMap["to"] != nil {
|
| 63 |
-
aux := common.HexToAddress(rawTransactionMap["to"].(string))
|
| 64 |
-
to = &aux
|
| 65 |
-
}
|
| 66 |
-
value := hex.DecodeBig(rawTransactionMap["value"].(string))
|
| 67 |
-
data, _ := hex.DecodeHex(rawTransactionMap["input"].(string))
|
| 68 |
-
v := hex.DecodeBig(rawTransactionMap["v"].(string))
|
| 69 |
-
r := hex.DecodeBig(rawTransactionMap["r"].(string))
|
| 70 |
-
s := hex.DecodeBig(rawTransactionMap["s"].(string))
|
| 71 |
-
|
| 72 |
-
tx := ethTypes.NewTx(ðTypes.LegacyTx{
|
| 73 |
-
Nonce: nonce, GasPrice: gasPrice, Gas: gas, To: to,
|
| 74 |
-
Value: value, Data: data, V: v, R: r, S: s,
|
| 75 |
-
})
|
| 76 |
-
txs = append(txs, tx)
|
| 77 |
-
|
| 78 |
-
hash := rawTransactionMap["hash"].(string)
|
| 79 |
-
printfLn("getting receipt for tx: %v", hash)
|
| 80 |
-
receiptResponse, err := client.JSONRPCCall(networkURL, "eth_getTransactionReceipt", hash)
|
| 81 |
-
chkErr(err)
|
| 82 |
-
chkRespErr(receiptResponse.Error)
|
| 83 |
-
|
| 84 |
-
rawReceipt := map[string]interface{}{}
|
| 85 |
-
err = json.Unmarshal(receiptResponse.Result, &rawReceipt)
|
| 86 |
-
chkErr(err)
|
| 87 |
-
|
| 88 |
-
receiptType := uint8(hex.DecodeUint64(rawReceipt["type"].(string)))
|
| 89 |
-
postState := common.HexToHash(rawReceipt["root"].(string)).Bytes()
|
| 90 |
-
status := hex.DecodeUint64(rawReceipt["status"].(string))
|
| 91 |
-
cumulativeGasUsed := hex.DecodeUint64(rawReceipt["cumulativeGasUsed"].(string))
|
| 92 |
-
txHash := common.HexToHash(rawReceipt["transactionHash"].(string))
|
| 93 |
-
var contractAddress common.Address
|
| 94 |
-
if rawReceipt["contractAddress"] != nil {
|
| 95 |
-
contractAddress = common.HexToAddress(rawReceipt["contractAddress"].(string))
|
| 96 |
-
}
|
| 97 |
-
gasUsed := hex.DecodeUint64(rawReceipt["gasUsed"].(string))
|
| 98 |
-
blockHash := common.HexToHash(rawReceipt["blockHash"].(string))
|
| 99 |
-
blockNumber := hex.DecodeBig(rawReceipt["blockNumber"].(string))
|
| 100 |
-
transactionIndex := uint(hex.DecodeUint64(rawReceipt["transactionIndex"].(string)))
|
| 101 |
-
|
| 102 |
-
receipt := ðTypes.Receipt{
|
| 103 |
-
Type: receiptType, PostState: postState, Status: status, CumulativeGasUsed: cumulativeGasUsed,
|
| 104 |
-
TxHash: txHash, ContractAddress: contractAddress, GasUsed: gasUsed,
|
| 105 |
-
BlockHash: blockHash, BlockNumber: blockNumber, TransactionIndex: transactionIndex,
|
| 106 |
-
}
|
| 107 |
-
|
| 108 |
-
rawLogs := rawReceipt["logs"].([]interface{})
|
| 109 |
-
logs := make([]*ethTypes.Log, 0, len(rawLogs))
|
| 110 |
-
printfLn("logs: %v", len(rawLogs))
|
| 111 |
-
for _, rawLog := range rawLogs {
|
| 112 |
-
rawLogMap := rawLog.(map[string]interface{})
|
| 113 |
-
|
| 114 |
-
address := common.HexToAddress(rawLogMap["address"].(string))
|
| 115 |
-
data, _ := hex.DecodeHex(rawLogMap["data"].(string))
|
| 116 |
-
blockNumber := hex.DecodeUint64(rawLogMap["blockNumber"].(string))
|
| 117 |
-
txHash := common.HexToHash(rawLogMap["transactionHash"].(string))
|
| 118 |
-
txIndex := uint(hex.DecodeUint64(rawLogMap["transactionIndex"].(string)))
|
| 119 |
-
blockHash := common.HexToHash(rawLogMap["blockHash"].(string))
|
| 120 |
-
index := uint(hex.DecodeUint64(rawLogMap["logIndex"].(string)))
|
| 121 |
-
removed := rawLogMap["removed"].(bool)
|
| 122 |
-
|
| 123 |
-
log := ðTypes.Log{
|
| 124 |
-
Address: address,
|
| 125 |
-
Data: data,
|
| 126 |
-
BlockNumber: blockNumber,
|
| 127 |
-
TxHash: txHash,
|
| 128 |
-
TxIndex: txIndex,
|
| 129 |
-
BlockHash: blockHash,
|
| 130 |
-
Index: index,
|
| 131 |
-
Removed: removed,
|
| 132 |
-
}
|
| 133 |
-
logs = append(logs, log)
|
| 134 |
-
|
| 135 |
-
rawTopics := rawLogMap["topics"].([]interface{})
|
| 136 |
-
topics := make([]common.Hash, 0, len(rawTopics))
|
| 137 |
-
for _, rawTopic := range rawTopics {
|
| 138 |
-
topic := common.HexToHash(rawTopic.(string))
|
| 139 |
-
topics = append(topics, topic)
|
| 140 |
-
}
|
| 141 |
-
log.Topics = topics
|
| 142 |
-
}
|
| 143 |
-
receipt.Logs = logs
|
| 144 |
-
|
| 145 |
-
// RPC is not setting the receipt bloom when computing the block hash
|
| 146 |
-
// receipt.Bloom = ethTypes.CreateBloom([]*ethTypes.Receipt{receipt})
|
| 147 |
-
|
| 148 |
-
receipts = append(receipts, receipt)
|
| 149 |
-
}
|
| 150 |
-
|
| 151 |
-
uncles := []*ethTypes.Header{}
|
| 152 |
-
|
| 153 |
-
builtBlock := ethTypes.NewBlock(header, txs, uncles, receipts, &trie.StackTrie{})
|
| 154 |
-
|
| 155 |
-
match := rawBlockHash == builtBlock.Hash().String()
|
| 156 |
-
|
| 157 |
-
log.Infof(" RPC block hash: %v", rawBlockHash)
|
| 158 |
-
log.Infof("Computed block hash: %v", builtBlock.Hash().String())
|
| 159 |
-
if !match {
|
| 160 |
-
log.Errorf(" block hashes DO NOT match")
|
| 161 |
-
} else {
|
| 162 |
-
log.Infof(" block hashes MATCH")
|
| 163 |
-
}
|
| 164 |
-
}
|
| 165 |
-
}
|
| 166 |
-
|
| 167 |
-
func chkRespErr(err *types.ErrorObject) {
|
| 168 |
-
if err != nil {
|
| 169 |
-
errMsg := fmt.Sprintf("%v %v", err.Code, err.Message)
|
| 170 |
-
errorfLn(errMsg)
|
| 171 |
-
panic(err)
|
| 172 |
-
}
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
func chkErr(err error) {
|
| 176 |
-
if err != nil {
|
| 177 |
-
errorfLn(err.Error())
|
| 178 |
-
panic(err)
|
| 179 |
-
}
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
-
func errorfLn(format string, args ...interface{}) {
|
| 183 |
-
printfLn("ERROR: "+format, args...)
|
| 184 |
-
}
|
| 185 |
-
|
| 186 |
-
func printfLn(format string, args ...interface{}) {
|
| 187 |
-
fmt.Printf(format+" \n", args...)
|
| 188 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,161 +0,0 @@
|
|
| 1 |
-
package main
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
"fmt"
|
| 6 |
-
"math/big"
|
| 7 |
-
"os"
|
| 8 |
-
"os/signal"
|
| 9 |
-
"sync"
|
| 10 |
-
"sync/atomic"
|
| 11 |
-
"syscall"
|
| 12 |
-
"time"
|
| 13 |
-
|
| 14 |
-
"github.com/ethereum/go-ethereum"
|
| 15 |
-
"github.com/ethereum/go-ethereum/core/types"
|
| 16 |
-
"github.com/ethereum/go-ethereum/ethclient"
|
| 17 |
-
"github.com/ethereum/go-ethereum/rpc"
|
| 18 |
-
)
|
| 19 |
-
|
| 20 |
-
func main() {
|
| 21 |
-
const httpUrl = "https://zkevm-rpc.com"
|
| 22 |
-
const wsUrl = "wss://ws.zkevm-rpc.com"
|
| 23 |
-
|
| 24 |
-
const numberOfConnections = 10
|
| 25 |
-
const intervalToCheckBlockNumber = 2 * time.Second
|
| 26 |
-
|
| 27 |
-
const enableLogSubscription = true
|
| 28 |
-
|
| 29 |
-
wg := sync.WaitGroup{}
|
| 30 |
-
wg.Add(numberOfConnections)
|
| 31 |
-
for connID := 0; connID < numberOfConnections; connID++ {
|
| 32 |
-
go func(connID int) {
|
| 33 |
-
ctx := context.Background()
|
| 34 |
-
|
| 35 |
-
logf(connID, "connecting to: %v\n", httpUrl)
|
| 36 |
-
httpClient, err := ethclient.Dial(httpUrl)
|
| 37 |
-
chkErr(connID, err)
|
| 38 |
-
logf(connID, "connected to: %v\n", httpUrl)
|
| 39 |
-
|
| 40 |
-
latestBlockNumber, err := httpClient.BlockNumber(ctx)
|
| 41 |
-
chkErr(connID, err)
|
| 42 |
-
|
| 43 |
-
logf(connID, "connecting to: %v\n", wsUrl)
|
| 44 |
-
wsClient, err := ethclient.Dial(wsUrl)
|
| 45 |
-
chkErr(connID, err)
|
| 46 |
-
logf(connID, "connected to: %v\n", wsUrl)
|
| 47 |
-
|
| 48 |
-
signals := make(chan os.Signal, 100)
|
| 49 |
-
signal.Notify(signals, os.Interrupt, syscall.SIGTERM)
|
| 50 |
-
|
| 51 |
-
lastWSBlockNumber := uint64(0)
|
| 52 |
-
numberOfLogsReceived := uint64(0)
|
| 53 |
-
|
| 54 |
-
// concurrently check block synchronization and logs received
|
| 55 |
-
go func(connID int, httpClient *ethclient.Client) {
|
| 56 |
-
for {
|
| 57 |
-
if lastWSBlockNumber != 0 {
|
| 58 |
-
httpBlockNumber, err := httpClient.BlockNumber(ctx)
|
| 59 |
-
if err != nil {
|
| 60 |
-
logf(connID, "%v failed to check block sync, retrying...\n", time.Now().Format(time.RFC3339Nano))
|
| 61 |
-
time.Sleep(intervalToCheckBlockNumber)
|
| 62 |
-
continue
|
| 63 |
-
}
|
| 64 |
-
|
| 65 |
-
wsBlockNumber := atomic.LoadUint64(&lastWSBlockNumber)
|
| 66 |
-
|
| 67 |
-
diff := httpBlockNumber - wsBlockNumber
|
| 68 |
-
logf(connID, "%v wsBlockNumber: %v httpBlockNumber: %v diff: %v\n", time.Now().Format(time.RFC3339Nano), wsBlockNumber, httpBlockNumber, diff)
|
| 69 |
-
}
|
| 70 |
-
if numberOfLogsReceived > 0 {
|
| 71 |
-
logf(connID, "%v logs received: %v\n", time.Now().Format(time.RFC3339Nano), numberOfLogsReceived)
|
| 72 |
-
}
|
| 73 |
-
|
| 74 |
-
time.Sleep(intervalToCheckBlockNumber)
|
| 75 |
-
}
|
| 76 |
-
}(connID, httpClient)
|
| 77 |
-
|
| 78 |
-
newHeaders := make(chan *types.Header)
|
| 79 |
-
subHeaders, err := wsClient.SubscribeNewHead(ctx, newHeaders)
|
| 80 |
-
chkErr(connID, err)
|
| 81 |
-
logf(connID, "subscribed to newHeads\n")
|
| 82 |
-
|
| 83 |
-
newLogs := make(chan types.Log)
|
| 84 |
-
var subLogs ethereum.Subscription = &rpc.ClientSubscription{}
|
| 85 |
-
if enableLogSubscription {
|
| 86 |
-
subLogs, err = wsClient.SubscribeFilterLogs(ctx, ethereum.FilterQuery{
|
| 87 |
-
FromBlock: big.NewInt(0).SetUint64(latestBlockNumber),
|
| 88 |
-
ToBlock: big.NewInt(0).SetUint64(latestBlockNumber + 10000),
|
| 89 |
-
}, newLogs)
|
| 90 |
-
chkErr(connID, err)
|
| 91 |
-
logf(connID, "subscribed to filterLogs\n")
|
| 92 |
-
}
|
| 93 |
-
|
| 94 |
-
// concurrently infinite sending messages
|
| 95 |
-
go func(connID int, ctx context.Context, wsClient *ethclient.Client) {
|
| 96 |
-
for {
|
| 97 |
-
//bn, err := wsClient.BlockNumber(ctx)
|
| 98 |
-
_, err := wsClient.BlockNumber(ctx)
|
| 99 |
-
if err != nil {
|
| 100 |
-
errorf(connID, "ERROR: %v\n", err.Error())
|
| 101 |
-
}
|
| 102 |
-
// logf(connID, "block number retrieved via message: %v\n", bn)
|
| 103 |
-
time.Sleep(time.Second)
|
| 104 |
-
}
|
| 105 |
-
}(connID, ctx, wsClient)
|
| 106 |
-
|
| 107 |
-
out:
|
| 108 |
-
for {
|
| 109 |
-
select {
|
| 110 |
-
case err := <-subHeaders.Err():
|
| 111 |
-
if err != nil {
|
| 112 |
-
errorf(connID, "%v\n", err.Error())
|
| 113 |
-
wg.Done()
|
| 114 |
-
break out
|
| 115 |
-
}
|
| 116 |
-
case err := <-subLogs.Err():
|
| 117 |
-
if err != nil {
|
| 118 |
-
errorf(connID, "%v\n", err.Error())
|
| 119 |
-
wg.Done()
|
| 120 |
-
break out
|
| 121 |
-
}
|
| 122 |
-
case header := <-newHeaders:
|
| 123 |
-
atomic.StoreUint64(&lastWSBlockNumber, header.Number.Uint64())
|
| 124 |
-
// logf(connID, "%v L2 Block Received: %v\n", time.Now().Format(time.RFC3339Nano), header.Number.Uint64())
|
| 125 |
-
case <-newLogs:
|
| 126 |
-
atomic.AddUint64(&numberOfLogsReceived, 1)
|
| 127 |
-
// logf(connID, "%v Log Received: %v - %v\n", time.Now().Format(time.RFC3339Nano), log.TxHash.String(), log.Index)
|
| 128 |
-
case <-signals:
|
| 129 |
-
subHeaders.Unsubscribe()
|
| 130 |
-
if enableLogSubscription {
|
| 131 |
-
subLogs.Unsubscribe()
|
| 132 |
-
}
|
| 133 |
-
logf(connID, "unsubscribed\n")
|
| 134 |
-
close(newHeaders)
|
| 135 |
-
close(newLogs)
|
| 136 |
-
wg.Done()
|
| 137 |
-
break out
|
| 138 |
-
}
|
| 139 |
-
}
|
| 140 |
-
}(connID)
|
| 141 |
-
}
|
| 142 |
-
wg.Wait()
|
| 143 |
-
}
|
| 144 |
-
|
| 145 |
-
func chkErr(connID int, err error) {
|
| 146 |
-
if err != nil {
|
| 147 |
-
errorf(connID, err.Error())
|
| 148 |
-
os.Exit(0)
|
| 149 |
-
}
|
| 150 |
-
}
|
| 151 |
-
|
| 152 |
-
func logf(connID int, format string, args ...any) {
|
| 153 |
-
msg := fmt.Sprintf(format, args...)
|
| 154 |
-
fmt.Printf("[connID: %v] %v", connID, msg)
|
| 155 |
-
}
|
| 156 |
-
|
| 157 |
-
func errorf(connID int, format string, args ...any) {
|
| 158 |
-
msg := fmt.Sprintf(format, args...)
|
| 159 |
-
msg = fmt.Sprintf("*****ERROR: %v", msg)
|
| 160 |
-
logf(connID, msg)
|
| 161 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -125,13 +125,13 @@
|
|
| 125 |
}
|
| 126 |
// Create smc client
|
| 127 |
zkevmAddr := common.HexToAddress(cliCtx.String(flagZkevmAddrName))
|
| 128 |
-
zkevm, err :=
|
| 129 |
if err != nil {
|
| 130 |
return err
|
| 131 |
}
|
| 132 |
|
| 133 |
rollupManagerAddr := common.HexToAddress(cliCtx.String(flagRollupManagerAddrName))
|
| 134 |
-
rollupManager, err :=
|
| 135 |
if err != nil {
|
| 136 |
return err
|
| 137 |
}
|
|
|
|
| 125 |
}
|
| 126 |
// Create smc client
|
| 127 |
zkevmAddr := common.HexToAddress(cliCtx.String(flagZkevmAddrName))
|
| 128 |
+
zkevm, err := polygonzkevm.NewPolygonzkevm(zkevmAddr, ethClient)
|
| 129 |
if err != nil {
|
| 130 |
return err
|
| 131 |
}
|
| 132 |
|
| 133 |
rollupManagerAddr := common.HexToAddress(cliCtx.String(flagRollupManagerAddrName))
|
| 134 |
+
rollupManager, err := polygonrollupmanager.NewPolygonrollupmanager(rollupManagerAddr, ethClient)
|
| 135 |
if err != nil {
|
| 136 |
return err
|
| 137 |
}
|
|
@@ -98,8 +98,8 @@
|
|
| 98 |
return err
|
| 99 |
}
|
| 100 |
// Create smc client
|
| 101 |
-
|
| 102 |
-
|
| 103 |
if err != nil {
|
| 104 |
return err
|
| 105 |
}
|
|
@@ -111,7 +111,7 @@
|
|
| 111 |
|
| 112 |
log.Info("Using address: ", auth.From)
|
| 113 |
|
| 114 |
-
num, err :=
|
| 115 |
if err != nil {
|
| 116 |
log.Error("error getting lastForBatch number. Error : ", err)
|
| 117 |
return err
|
|
@@ -130,14 +130,14 @@
|
|
| 130 |
log.Error("error decoding txs. Error: ", err)
|
| 131 |
return err
|
| 132 |
}
|
| 133 |
-
fbData := []
|
| 134 |
Transactions: transactions,
|
| 135 |
ForcedGlobalExitRoot: common.HexToHash(cliCtx.String(flagGerName)),
|
| 136 |
ForcedTimestamp: cliCtx.Uint64(flagTimestampName),
|
| 137 |
}}
|
| 138 |
log.Warnf("%v, %+v", cliCtx.String(flagTransactionsName), fbData)
|
| 139 |
// Send forceBatch
|
| 140 |
-
tx, err :=
|
| 141 |
if err != nil {
|
| 142 |
log.Error("error sending forceBatch. Error: ", err)
|
| 143 |
return err
|
|
|
|
| 98 |
return err
|
| 99 |
}
|
| 100 |
// Create smc client
|
| 101 |
+
poeAddr := common.HexToAddress(cliCtx.String(flagSmcAddrName))
|
| 102 |
+
poe, err := polygonzkevm.NewPolygonzkevm(poeAddr, ethClient)
|
| 103 |
if err != nil {
|
| 104 |
return err
|
| 105 |
}
|
|
|
|
| 111 |
|
| 112 |
log.Info("Using address: ", auth.From)
|
| 113 |
|
| 114 |
+
num, err := poe.LastForceBatch(&bind.CallOpts{Pending: false})
|
| 115 |
if err != nil {
|
| 116 |
log.Error("error getting lastForBatch number. Error : ", err)
|
| 117 |
return err
|
|
|
|
| 130 |
log.Error("error decoding txs. Error: ", err)
|
| 131 |
return err
|
| 132 |
}
|
| 133 |
+
fbData := []polygonzkevm.PolygonRollupBaseEtrogBatchData{{
|
| 134 |
Transactions: transactions,
|
| 135 |
ForcedGlobalExitRoot: common.HexToHash(cliCtx.String(flagGerName)),
|
| 136 |
ForcedTimestamp: cliCtx.Uint64(flagTimestampName),
|
| 137 |
}}
|
| 138 |
log.Warnf("%v, %+v", cliCtx.String(flagTransactionsName), fbData)
|
| 139 |
// Send forceBatch
|
| 140 |
+
tx, err := poe.SequenceForceBatches(auth, fbData)
|
| 141 |
if err != nil {
|
| 142 |
log.Error("error sending forceBatch. Error: ", err)
|
| 143 |
return err
|
|
@@ -63,13 +63,6 @@
|
|
| 63 |
Required: true,
|
| 64 |
}
|
| 65 |
|
| 66 |
-
batchFlag = cli.Uint64Flag{
|
| 67 |
-
Name: "batch",
|
| 68 |
-
Aliases: []string{"bn"},
|
| 69 |
-
Usage: "batch `NUMBER`",
|
| 70 |
-
Required: true,
|
| 71 |
-
}
|
| 72 |
-
|
| 73 |
updateFileFlag = cli.BoolFlag{
|
| 74 |
Name: "update",
|
| 75 |
Aliases: []string{"u"},
|
|
@@ -126,16 +119,6 @@
|
|
| 126 |
},
|
| 127 |
},
|
| 128 |
{
|
| 129 |
-
Name: "decode-batch-offline",
|
| 130 |
-
Aliases: []string{},
|
| 131 |
-
Usage: "Decodes a batch offline",
|
| 132 |
-
Action: decodeBatchOffline,
|
| 133 |
-
Flags: []cli.Flag{
|
| 134 |
-
&configFileFlag,
|
| 135 |
-
&batchFlag,
|
| 136 |
-
},
|
| 137 |
-
},
|
| 138 |
-
{
|
| 139 |
Name: "decode-entry",
|
| 140 |
Aliases: []string{},
|
| 141 |
Usage: "Decodes an entry",
|
|
@@ -156,16 +139,6 @@
|
|
| 156 |
},
|
| 157 |
},
|
| 158 |
{
|
| 159 |
-
Name: "decode-batch",
|
| 160 |
-
Aliases: []string{},
|
| 161 |
-
Usage: "Decodes a batch",
|
| 162 |
-
Action: decodeBatch,
|
| 163 |
-
Flags: []cli.Flag{
|
| 164 |
-
&configFileFlag,
|
| 165 |
-
&batchFlag,
|
| 166 |
-
},
|
| 167 |
-
},
|
| 168 |
-
{
|
| 169 |
Name: "truncate",
|
| 170 |
Aliases: []string{},
|
| 171 |
Usage: "Truncates the stream file",
|
|
@@ -234,7 +207,7 @@
|
|
| 234 |
stateTree := merkletree.NewStateTree(mtDBServiceClient)
|
| 235 |
log.Debug("Connected to the merkle tree")
|
| 236 |
|
| 237 |
-
stateDB := state.NewState(state.Config{}, stateDBStorage, nil, stateTree, nil, nil
|
| 238 |
|
| 239 |
// Calculate intermediate state roots
|
| 240 |
var imStateRoots map[uint64][]byte
|
|
@@ -326,11 +299,6 @@
|
|
| 326 |
log.Errorf("Error: %v\n", err)
|
| 327 |
os.Exit(1)
|
| 328 |
}
|
| 329 |
-
|
| 330 |
-
if common.BytesToHash(imStateRoot.Bytes()) == state.ZeroHash && x != 0 {
|
| 331 |
-
break
|
| 332 |
-
}
|
| 333 |
-
|
| 334 |
imStateRootMux.Lock()
|
| 335 |
(*isStateRoots)[x] = imStateRoot.Bytes()
|
| 336 |
imStateRootMux.Unlock()
|
|
@@ -657,71 +625,6 @@
|
|
| 657 |
return nil
|
| 658 |
}
|
| 659 |
|
| 660 |
-
func decodeBatch(cliCtx *cli.Context) error {
|
| 661 |
-
c, err := config.Load(cliCtx)
|
| 662 |
-
if err != nil {
|
| 663 |
-
log.Error(err)
|
| 664 |
-
os.Exit(1)
|
| 665 |
-
}
|
| 666 |
-
|
| 667 |
-
log.Init(c.Log)
|
| 668 |
-
|
| 669 |
-
client, err := datastreamer.NewClient(c.Online.URI, c.Online.StreamType)
|
| 670 |
-
if err != nil {
|
| 671 |
-
log.Error(err)
|
| 672 |
-
os.Exit(1)
|
| 673 |
-
}
|
| 674 |
-
|
| 675 |
-
err = client.Start()
|
| 676 |
-
if err != nil {
|
| 677 |
-
log.Error(err)
|
| 678 |
-
os.Exit(1)
|
| 679 |
-
}
|
| 680 |
-
|
| 681 |
-
batchNumber := cliCtx.Uint64("batch")
|
| 682 |
-
|
| 683 |
-
bookMark := state.DSBookMark{
|
| 684 |
-
Type: state.BookMarkTypeBatch,
|
| 685 |
-
Value: batchNumber,
|
| 686 |
-
}
|
| 687 |
-
|
| 688 |
-
firstEntry, err := client.ExecCommandGetBookmark(bookMark.Encode())
|
| 689 |
-
if err != nil {
|
| 690 |
-
log.Error(err)
|
| 691 |
-
os.Exit(1)
|
| 692 |
-
}
|
| 693 |
-
printEntry(firstEntry)
|
| 694 |
-
|
| 695 |
-
secondEntry, err := client.ExecCommandGetEntry(firstEntry.Number + 1)
|
| 696 |
-
if err != nil {
|
| 697 |
-
log.Error(err)
|
| 698 |
-
os.Exit(1)
|
| 699 |
-
}
|
| 700 |
-
printEntry(secondEntry)
|
| 701 |
-
|
| 702 |
-
i := uint64(2) //nolint:gomnd
|
| 703 |
-
for {
|
| 704 |
-
entry, err := client.ExecCommandGetEntry(firstEntry.Number + i)
|
| 705 |
-
if err != nil {
|
| 706 |
-
log.Error(err)
|
| 707 |
-
os.Exit(1)
|
| 708 |
-
}
|
| 709 |
-
|
| 710 |
-
if entry.Type == state.EntryTypeBookMark {
|
| 711 |
-
bookMark := state.DSBookMark{}.Decode(entry.Data)
|
| 712 |
-
if bookMark.Type == state.BookMarkTypeBatch {
|
| 713 |
-
break
|
| 714 |
-
}
|
| 715 |
-
}
|
| 716 |
-
|
| 717 |
-
secondEntry = entry
|
| 718 |
-
printEntry(secondEntry)
|
| 719 |
-
i++
|
| 720 |
-
}
|
| 721 |
-
|
| 722 |
-
return nil
|
| 723 |
-
}
|
| 724 |
-
|
| 725 |
func decodeEntryOffline(cliCtx *cli.Context) error {
|
| 726 |
c, err := config.Load(cliCtx)
|
| 727 |
if err != nil {
|
|
@@ -794,64 +697,6 @@
|
|
| 794 |
printEntry(secondEntry)
|
| 795 |
i++
|
| 796 |
}
|
| 797 |
-
|
| 798 |
-
return nil
|
| 799 |
-
}
|
| 800 |
-
|
| 801 |
-
func decodeBatchOffline(cliCtx *cli.Context) error {
|
| 802 |
-
c, err := config.Load(cliCtx)
|
| 803 |
-
if err != nil {
|
| 804 |
-
log.Error(err)
|
| 805 |
-
os.Exit(1)
|
| 806 |
-
}
|
| 807 |
-
|
| 808 |
-
log.Init(c.Log)
|
| 809 |
-
|
| 810 |
-
streamServer, err := initializeStreamServer(c)
|
| 811 |
-
if err != nil {
|
| 812 |
-
log.Error(err)
|
| 813 |
-
os.Exit(1)
|
| 814 |
-
}
|
| 815 |
-
|
| 816 |
-
batchNumber := cliCtx.Uint64("batch")
|
| 817 |
-
|
| 818 |
-
bookMark := state.DSBookMark{
|
| 819 |
-
Type: state.BookMarkTypeL2Block,
|
| 820 |
-
Value: batchNumber,
|
| 821 |
-
}
|
| 822 |
-
|
| 823 |
-
firstEntry, err := streamServer.GetFirstEventAfterBookmark(bookMark.Encode())
|
| 824 |
-
if err != nil {
|
| 825 |
-
log.Error(err)
|
| 826 |
-
os.Exit(1)
|
| 827 |
-
}
|
| 828 |
-
printEntry(firstEntry)
|
| 829 |
-
|
| 830 |
-
secondEntry, err := streamServer.GetEntry(firstEntry.Number + 1)
|
| 831 |
-
if err != nil {
|
| 832 |
-
log.Error(err)
|
| 833 |
-
os.Exit(1)
|
| 834 |
-
}
|
| 835 |
-
|
| 836 |
-
i := uint64(2) //nolint:gomnd
|
| 837 |
-
printEntry(secondEntry)
|
| 838 |
-
for {
|
| 839 |
-
secondEntry, err = streamServer.GetEntry(firstEntry.Number + i)
|
| 840 |
-
if err != nil {
|
| 841 |
-
log.Error(err)
|
| 842 |
-
os.Exit(1)
|
| 843 |
-
}
|
| 844 |
-
|
| 845 |
-
if secondEntry.Type == state.EntryTypeBookMark {
|
| 846 |
-
bookMark := state.DSBookMark{}.Decode(secondEntry.Data)
|
| 847 |
-
if bookMark.Type == state.BookMarkTypeBatch {
|
| 848 |
-
break
|
| 849 |
-
}
|
| 850 |
-
}
|
| 851 |
-
|
| 852 |
-
printEntry(secondEntry)
|
| 853 |
-
i++
|
| 854 |
-
}
|
| 855 |
|
| 856 |
return nil
|
| 857 |
}
|
|
|
|
| 63 |
Required: true,
|
| 64 |
}
|
| 65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
updateFileFlag = cli.BoolFlag{
|
| 67 |
Name: "update",
|
| 68 |
Aliases: []string{"u"},
|
|
|
|
| 119 |
},
|
| 120 |
},
|
| 121 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
Name: "decode-entry",
|
| 123 |
Aliases: []string{},
|
| 124 |
Usage: "Decodes an entry",
|
|
|
|
| 139 |
},
|
| 140 |
},
|
| 141 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
Name: "truncate",
|
| 143 |
Aliases: []string{},
|
| 144 |
Usage: "Truncates the stream file",
|
|
|
|
| 207 |
stateTree := merkletree.NewStateTree(mtDBServiceClient)
|
| 208 |
log.Debug("Connected to the merkle tree")
|
| 209 |
|
| 210 |
+
stateDB := state.NewState(state.Config{}, stateDBStorage, nil, stateTree, nil, nil)
|
| 211 |
|
| 212 |
// Calculate intermediate state roots
|
| 213 |
var imStateRoots map[uint64][]byte
|
|
|
|
| 299 |
log.Errorf("Error: %v\n", err)
|
| 300 |
os.Exit(1)
|
| 301 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
imStateRootMux.Lock()
|
| 303 |
(*isStateRoots)[x] = imStateRoot.Bytes()
|
| 304 |
imStateRootMux.Unlock()
|
|
|
|
| 625 |
return nil
|
| 626 |
}
|
| 627 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 628 |
func decodeEntryOffline(cliCtx *cli.Context) error {
|
| 629 |
c, err := config.Load(cliCtx)
|
| 630 |
if err != nil {
|
|
|
|
| 697 |
printEntry(secondEntry)
|
| 698 |
i++
|
| 699 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 700 |
|
| 701 |
return nil
|
| 702 |
}
|
|
@@ -27,10 +27,6 @@
|
|
| 27 |
decode-l2block: ## Runs the tool to decode a given L2 block
|
| 28 |
go run main.go decode-l2block -cfg config/tool.config.toml -l2block $(arguments)
|
| 29 |
|
| 30 |
-
.PHONY: decode-batch
|
| 31 |
-
decode-batch: ## Runs the tool to decode a given batch
|
| 32 |
-
go run main.go decode-batch -cfg config/tool.config.toml -batch $(arguments)
|
| 33 |
-
|
| 34 |
.PHONY: decode-entry-offline
|
| 35 |
decode-entry-offline: ## Runs the offline tool to decode a given entry number
|
| 36 |
go run main.go decode-entry-offline -cfg config/tool.config.toml -entry $(arguments)
|
|
@@ -39,10 +35,6 @@
|
|
| 39 |
decode-l2block-offline: ## Runs the offline tool to decode a given L2 block
|
| 40 |
go run main.go decode-l2block-offline -cfg config/tool.config.toml -l2block $(arguments)
|
| 41 |
|
| 42 |
-
.PHONY: decode-batch-offline
|
| 43 |
-
decode-batch-offline: ## Runs the offline tool to decode a given batch
|
| 44 |
-
go run main.go decode-batch-offline -cfg config/tool.config.toml -batch $(arguments)
|
| 45 |
-
|
| 46 |
.PHONY: truncate
|
| 47 |
truncate: ## Runs the offline tool to truncate the stream file
|
| 48 |
go run main.go truncate -cfg config/tool.config.toml -entry $(arguments)
|
|
|
|
| 27 |
decode-l2block: ## Runs the tool to decode a given L2 block
|
| 28 |
go run main.go decode-l2block -cfg config/tool.config.toml -l2block $(arguments)
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
.PHONY: decode-entry-offline
|
| 31 |
decode-entry-offline: ## Runs the offline tool to decode a given entry number
|
| 32 |
go run main.go decode-entry-offline -cfg config/tool.config.toml -entry $(arguments)
|
|
|
|
| 35 |
decode-l2block-offline: ## Runs the offline tool to decode a given L2 block
|
| 36 |
go run main.go decode-l2block-offline -cfg config/tool.config.toml -l2block $(arguments)
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
.PHONY: truncate
|
| 39 |
truncate: ## Runs the offline tool to truncate the stream file
|
| 40 |
go run main.go truncate -cfg config/tool.config.toml -entry $(arguments)
|
|
@@ -25,45 +25,36 @@
|
|
| 25 |
)
|
| 26 |
|
| 27 |
var (
|
| 28 |
-
showErrors
|
| 29 |
-
showLosses
|
| 30 |
-
showReprocess
|
| 31 |
-
showDetail
|
| 32 |
-
showAlways
|
| 33 |
-
showOnlyCfg
|
| 34 |
-
useRealL2GasPrice bool
|
| 35 |
-
showDiscrepancy uint64
|
| 36 |
-
showEncoded bool
|
| 37 |
)
|
| 38 |
|
| 39 |
const (
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
fixedBytesTx = signatureBytes + effectivePctBytes
|
| 44 |
)
|
| 45 |
|
| 46 |
type egpConfig struct {
|
| 47 |
-
ByteGasCost
|
| 48 |
-
ZeroGasCost
|
| 49 |
-
NetProfitFactor
|
| 50 |
-
L1GasPriceFactor
|
| 51 |
-
L2GasPriceSugFactor
|
| 52 |
-
FinalDeviationPct
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
EthTransferL1GasPriceFactor float64 // Gas price for transfer (used if EthTransferGasPrice = 0)
|
| 56 |
}
|
| 57 |
|
| 58 |
type egpLogRecord struct {
|
| 59 |
l2BlockNum uint64
|
| 60 |
l2BlockReceived time.Time
|
| 61 |
encoded string
|
| 62 |
-
hash string
|
| 63 |
missingLogInfo bool // Flag if egp_log field is empty
|
| 64 |
-
realGasPrice float64 // (calculated field) Real price paid by the user (to perform a double check)
|
| 65 |
-
txZeroCount uint64 // (calculated field) count transaction zero bytes
|
| 66 |
-
txNonZeroCount uint64 // (calculated field) count transaction non zero bytes
|
| 67 |
LogError string `json:"Error"`
|
| 68 |
LogEnabled bool `json:"Enabled"`
|
| 69 |
LogL1GasPrice float64 `json:"L1GasPrice"` // L1 gas price
|
|
@@ -97,11 +88,10 @@
|
|
| 97 |
totalLoss float64 // Total loss gas amount
|
| 98 |
sumGasFinal float64 // Accumulated sum of final gas (to get average)
|
| 99 |
countGasFinal float64 // Count number of accumulated (to get average)
|
| 100 |
-
|
| 101 |
-
|
| 102 |
sumFee float64
|
| 103 |
-
|
| 104 |
-
sumRealGas float64
|
| 105 |
}
|
| 106 |
|
| 107 |
func main() {
|
|
@@ -140,20 +130,10 @@
|
|
| 140 |
Value: false,
|
| 141 |
},
|
| 142 |
&cli.BoolFlag{
|
| 143 |
-
Name: "showencoded",
|
| 144 |
-
Usage: "show encoded field when showing detail record",
|
| 145 |
-
Value: false,
|
| 146 |
-
},
|
| 147 |
-
&cli.BoolFlag{
|
| 148 |
Name: "showalways",
|
| 149 |
Usage: "show always full detailed record",
|
| 150 |
Value: false,
|
| 151 |
},
|
| 152 |
-
&cli.Uint64Flag{
|
| 153 |
-
Name: "showdiscrepancy",
|
| 154 |
-
Usage: "show discrepancies between real and simulated (0:none, 1:reprocess, 2:gasprice, 3:all)",
|
| 155 |
-
Value: ^uint64(0),
|
| 156 |
-
},
|
| 157 |
&cli.StringFlag{
|
| 158 |
Name: "cfg",
|
| 159 |
Aliases: []string{"c"},
|
|
@@ -165,11 +145,6 @@
|
|
| 165 |
Usage: "show only simulation results",
|
| 166 |
Value: false,
|
| 167 |
},
|
| 168 |
-
&cli.BoolFlag{
|
| 169 |
-
Name: "realgasprice",
|
| 170 |
-
Usage: "use real L2 gas price from egp-log instead of the calculated simulated value",
|
| 171 |
-
Value: false,
|
| 172 |
-
},
|
| 173 |
&cli.StringFlag{
|
| 174 |
Name: "db",
|
| 175 |
Usage: "DB connection string: \"host=xxx port=xxx user=xxx dbname=xxx password=xxx\"",
|
|
@@ -189,15 +164,14 @@
|
|
| 189 |
// defaultConfig parses the default configuration values
|
| 190 |
func defaultConfig() (*egpConfig, error) {
|
| 191 |
cfg := egpConfig{
|
| 192 |
-
ByteGasCost:
|
| 193 |
-
ZeroGasCost:
|
| 194 |
-
NetProfitFactor:
|
| 195 |
-
L1GasPriceFactor:
|
| 196 |
-
L2GasPriceSugFactor:
|
| 197 |
-
FinalDeviationPct:
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
EthTransferL1GasPriceFactor: 0.10, // nolint:gomnd
|
| 201 |
}
|
| 202 |
|
| 203 |
viper.SetConfigType("toml")
|
|
@@ -268,9 +242,6 @@
|
|
| 268 |
showDetail = ctx.Bool("showdetail")
|
| 269 |
showAlways = ctx.Bool("showalways")
|
| 270 |
showOnlyCfg = ctx.Bool("onlycfg")
|
| 271 |
-
useRealL2GasPrice = ctx.Bool("realgasprice")
|
| 272 |
-
showDiscrepancy = ctx.Uint64("showdiscrepancy")
|
| 273 |
-
showEncoded = ctx.Bool("showencoded")
|
| 274 |
|
| 275 |
// Load simulation config file
|
| 276 |
var err error
|
|
@@ -299,7 +270,7 @@
|
|
| 299 |
|
| 300 |
// Query data
|
| 301 |
query := fmt.Sprintf(`
|
| 302 |
-
select lb.received_at, t.l2_block_num, coalesce(t.egp_log::varchar,'') as egp_log, t.encoded
|
| 303 |
from state.transaction t
|
| 304 |
join state.l2block lb on lb.block_num = t.l2_block_num
|
| 305 |
where t.l2_block_num >= %d and t.l2_block_num <= %d`, fromBlock, toBlock)
|
|
@@ -315,14 +286,14 @@
|
|
| 315 |
logf("Starting from L2 block %d...", fromBlock)
|
| 316 |
var blockReceived time.Time
|
| 317 |
var l2Block uint64
|
| 318 |
-
var egpLog, encoded
|
|
|
|
| 319 |
var timeFirst, timeLast time.Time
|
| 320 |
-
var realStats, simulateStats egpStats
|
| 321 |
|
| 322 |
i := uint64(0)
|
| 323 |
for rows.Next() {
|
| 324 |
// Fetch row
|
| 325 |
-
err = rows.Scan(&blockReceived, &l2Block, &egpLog, &encoded
|
| 326 |
if err != nil {
|
| 327 |
logf("Error fetching row: %v", err)
|
| 328 |
return err
|
|
@@ -347,38 +318,31 @@
|
|
| 347 |
i++
|
| 348 |
|
| 349 |
// Transaction info
|
| 350 |
-
|
| 351 |
l2BlockReceived: blockReceived,
|
| 352 |
l2BlockNum: l2Block,
|
| 353 |
encoded: encoded,
|
| 354 |
-
hash: hash,
|
| 355 |
missingLogInfo: egpLog == "",
|
| 356 |
-
realGasPrice: 0,
|
| 357 |
-
txZeroCount: 0,
|
| 358 |
-
txNonZeroCount: 0,
|
| 359 |
}
|
| 360 |
|
| 361 |
// Check if EGP info is present
|
| 362 |
if egpLog != "" {
|
| 363 |
// Decode EGP log json
|
| 364 |
-
err = json.Unmarshal([]byte(egpLog), &
|
| 365 |
if err != nil {
|
| 366 |
logf("Error decoding json from egp_log field: %v", err)
|
| 367 |
return err
|
| 368 |
}
|
| 369 |
-
|
| 370 |
-
// Calculated fields
|
| 371 |
-
egpRealData.realGasPrice = roundEffectiveGasPrice(egpRealData.LogGasPrice, egpRealData.LogPercentage)
|
| 372 |
}
|
| 373 |
|
| 374 |
// Calculate stats
|
| 375 |
-
countStats(i, l2Block, &
|
| 376 |
|
| 377 |
// Simulate using alternative config
|
| 378 |
if egpCfg != nil {
|
| 379 |
-
egpSimData :=
|
| 380 |
simulateConfig(&egpSimData, egpCfg)
|
| 381 |
-
countStats(i, l2Block, &egpSimData, &simulateStats, egpCfg
|
| 382 |
}
|
| 383 |
}
|
| 384 |
|
|
@@ -389,39 +353,25 @@
|
|
| 389 |
logf("\nPERIOD [%.2f days]: %v ... %v", diff/24, timeFirst, timeLast) // nolint:gomnd
|
| 390 |
if !showOnlyCfg {
|
| 391 |
logf("\nEGP REAL STATS:")
|
| 392 |
-
printStats(&
|
| 393 |
}
|
| 394 |
|
| 395 |
// Print simulation stats results
|
| 396 |
if egpCfg != nil {
|
| 397 |
logf("\nEGP SIMULATION STATS:")
|
| 398 |
printStats(&simulateStats)
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
strL2SugFactor = "REAL-GASPRICE-USED"
|
| 402 |
-
} else {
|
| 403 |
-
strL2SugFactor = fmt.Sprintf("%.4f", egpCfg.L2GasPriceSugFactor)
|
| 404 |
-
}
|
| 405 |
-
logf("PARAMS: byte[%d] zero[%d] netFactor[%.4f] L1factor[%.4f] L2sugFactor[%s] devPct[%d] L2sugPreEGP[%.4f] EthTrsfPrice[%d] EthTrsfL1Fact[%.4f]", egpCfg.ByteGasCost,
|
| 406 |
-
egpCfg.ZeroGasCost, egpCfg.NetProfitFactor, egpCfg.L1GasPriceFactor, strL2SugFactor, egpCfg.FinalDeviationPct, egpCfg.L2GasPriceSugFactorPreEGP,
|
| 407 |
-
egpCfg.EthTransferGasPrice, egpCfg.EthTransferL1GasPriceFactor)
|
| 408 |
}
|
| 409 |
|
| 410 |
return nil
|
| 411 |
}
|
| 412 |
|
| 413 |
// countStats calculates and counts statistics for an EGP record
|
| 414 |
-
func countStats(i uint64, block uint64, egp *egpLogRecord, stats *egpStats, cfg *egpConfig
|
| 415 |
-
var title string
|
| 416 |
-
if cfg == nil {
|
| 417 |
-
title = "REAL EGP-LOG"
|
| 418 |
-
} else {
|
| 419 |
-
title = "SIM CONFIG"
|
| 420 |
-
}
|
| 421 |
-
|
| 422 |
// Show record information
|
| 423 |
if showAlways {
|
| 424 |
-
printEgpLogRecord(egp,
|
| 425 |
}
|
| 426 |
|
| 427 |
// Total transactions
|
|
@@ -433,7 +383,7 @@
|
|
| 433 |
if showErrors {
|
| 434 |
fmt.Printf("egp-error:#%d:(L2 block [%d] %v):%s\n", i, block, egp.l2BlockReceived, egp.LogError)
|
| 435 |
if showDetail && !showAlways {
|
| 436 |
-
printEgpLogRecord(egp,
|
| 437 |
}
|
| 438 |
}
|
| 439 |
}
|
|
@@ -454,7 +404,7 @@
|
|
| 454 |
if showReprocess {
|
| 455 |
fmt.Printf("egp-reprocess:#%d:(L2 block [%d] %v)\n", i, block, egp.l2BlockReceived)
|
| 456 |
if showDetail && !showAlways {
|
| 457 |
-
printEgpLogRecord(egp,
|
| 458 |
}
|
| 459 |
}
|
| 460 |
}
|
|
@@ -480,7 +430,6 @@
|
|
| 480 |
// Gas total and average
|
| 481 |
stats.countGasFinal++
|
| 482 |
stats.sumGasFinal += egp.LogValueFinal
|
| 483 |
-
stats.sumRealGas += egp.realGasPrice
|
| 484 |
|
| 485 |
// Gas total and average without EGP
|
| 486 |
var l2SugPreEGP float64
|
|
@@ -490,9 +439,9 @@
|
|
| 490 |
l2SugPreEGP = 0.1
|
| 491 |
}
|
| 492 |
|
| 493 |
-
stats.
|
| 494 |
-
stats.
|
| 495 |
-
stats.
|
| 496 |
|
| 497 |
// Loss
|
| 498 |
if egp.LogValueFinal == egp.LogGasPrice {
|
|
@@ -514,27 +463,10 @@
|
|
| 514 |
info := fmt.Sprintf("reprocess=%t, final=%.0f, egp1=%.0f, egp2=%.0f, user=%.0f", egp.LogReprocess, egp.LogValueFinal, egp.LogGasUsedFirst, egp.LogGasUsedSecond, egp.LogGasPrice)
|
| 515 |
fmt.Printf("egp-loss:#%d:(L2 block [%d] %v):loss=%.0f:info:%s\n", i, block, egp.l2BlockReceived, loss, info)
|
| 516 |
if showDetail && !showAlways {
|
| 517 |
-
printEgpLogRecord(egp,
|
| 518 |
}
|
| 519 |
}
|
| 520 |
}
|
| 521 |
-
|
| 522 |
-
// Show discrepancies
|
| 523 |
-
if showDiscrepancy > 0 && compareEgp != nil {
|
| 524 |
-
var discrepancy bool
|
| 525 |
-
if (showDiscrepancy == 2 || showDiscrepancy == 3) && egp.realGasPrice != compareEgp.realGasPrice {
|
| 526 |
-
discrepancy = true
|
| 527 |
-
fmt.Printf("egp-disc:realgas:#%d:(L2 block [%d] %v):sim=%0.f, real=%0.f\n", i, block, egp.l2BlockReceived, egp.realGasPrice, compareEgp.realGasPrice)
|
| 528 |
-
}
|
| 529 |
-
if (showDiscrepancy == 1 || showDiscrepancy == 3) && egp.LogReprocess != compareEgp.LogReprocess {
|
| 530 |
-
discrepancy = true
|
| 531 |
-
fmt.Printf("egp-disc:reprocess:#%d:(L2 block [%d] %v):sim=%t, real=%t\n", i, block, egp.l2BlockReceived, egp.LogReprocess, compareEgp.LogReprocess)
|
| 532 |
-
}
|
| 533 |
-
if discrepancy && showDetail && !showAlways {
|
| 534 |
-
printEgpLogRecord(compareEgp, showEncoded, "REAL", true)
|
| 535 |
-
printEgpLogRecord(egp, showEncoded, title, cfg == nil)
|
| 536 |
-
}
|
| 537 |
-
}
|
| 538 |
}
|
| 539 |
}
|
| 540 |
|
|
@@ -545,10 +477,9 @@
|
|
| 545 |
}
|
| 546 |
|
| 547 |
// printEgpLogRecord prints values of egpLogRecord struct
|
| 548 |
-
func printEgpLogRecord(record *egpLogRecord, showTxInfo bool
|
| 549 |
-
fmt.Printf("
|
| 550 |
fmt.Printf(" timestamp: [%v]\n", record.l2BlockReceived)
|
| 551 |
-
fmt.Printf(" hash: [%s]\n", record.hash)
|
| 552 |
fmt.Printf(" Error: [%s]\n", record.LogError)
|
| 553 |
fmt.Printf(" Enabled: [%t]\n", record.LogEnabled)
|
| 554 |
fmt.Printf(" L1GasPrice: [%.0f]\n", record.LogL1GasPrice)
|
|
@@ -565,11 +496,6 @@
|
|
| 565 |
fmt.Printf(" Percentage: [%d]\n", record.LogPercentage)
|
| 566 |
fmt.Printf(" MaxDeviation: [%.0f]\n", record.LogMaxDeviation)
|
| 567 |
fmt.Printf(" FinalDeviation: [%.0f]\n", record.LogFinalDeviation)
|
| 568 |
-
if !isReal {
|
| 569 |
-
fmt.Printf(" *zeroBytes: [%d]\n", record.txZeroCount)
|
| 570 |
-
fmt.Printf(" *nonZeroBytes: [%d]\n", record.txNonZeroCount)
|
| 571 |
-
}
|
| 572 |
-
fmt.Printf(" *realGasPrice: [%0.f]\n", record.realGasPrice)
|
| 573 |
if showTxInfo {
|
| 574 |
fmt.Printf(" encoded: [%s]\n", record.encoded)
|
| 575 |
}
|
|
@@ -617,33 +543,30 @@
|
|
| 617 |
fmt.Printf(" Tx fee avg...........: [%.0f] (%.3f GWei) (%.9f ETH)\n", stats.sumFee/stats.countGasFinal,
|
| 618 |
stats.sumFee/stats.countGasFinal/GWEI_DIV, stats.sumFee/stats.countGasFinal/ETH_DIV)
|
| 619 |
}
|
| 620 |
-
if stats.
|
| 621 |
-
fmt.Printf(" Gas pri.avg
|
| 622 |
-
stats.
|
| 623 |
-
}
|
| 624 |
-
if stats.
|
| 625 |
-
fmt.Printf(" Tx fee avg
|
| 626 |
-
stats.
|
| 627 |
-
}
|
| 628 |
-
fmt.Printf(" Diff fee EGP-
|
| 629 |
-
(stats.sumFee-stats.
|
| 630 |
-
fmt.Printf(" Loss count
|
| 631 |
-
fmt.Printf("
|
| 632 |
if stats.totalLossCount > 0 {
|
| 633 |
-
fmt.Printf("
|
| 634 |
stats.totalLoss/stats.totalLossCount/ETH_DIV)
|
| 635 |
}
|
| 636 |
-
fmt.Printf(" Real gas price total.: [%.0f] (%.3f GWei) (%.9f ETH)\n", stats.sumRealGas, stats.sumRealGas/GWEI_DIV, stats.sumRealGas/ETH_DIV)
|
| 637 |
}
|
| 638 |
}
|
| 639 |
|
| 640 |
// simulateConfig simulates scenario using received config
|
| 641 |
func simulateConfig(egp *egpLogRecord, cfg *egpConfig) {
|
| 642 |
// L2 and user gas price
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
egp.LogGasPrice = egp.LogL2GasPrice
|
| 646 |
-
}
|
| 647 |
|
| 648 |
// Compute EGP
|
| 649 |
var err error
|
|
@@ -679,64 +602,43 @@
|
|
| 679 |
egp.LogValueFinal = egp.LogGasPrice
|
| 680 |
}
|
| 681 |
}
|
| 682 |
-
// Gas price effective percentage
|
| 683 |
-
egp.LogPercentage = calcEffectivePercentage(egp.LogGasPrice, egp.LogValueFinal)
|
| 684 |
} else {
|
| 685 |
egp.LogValueSecond = 0
|
| 686 |
|
| 687 |
// Final gas: price signed
|
| 688 |
egp.LogValueFinal = egp.LogGasPrice
|
| 689 |
-
// Gas price effective percentage
|
| 690 |
-
egp.LogPercentage = uint64(state.MaxEffectivePercentage)
|
| 691 |
}
|
| 692 |
|
| 693 |
-
//
|
| 694 |
-
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
func calcEffectivePercentage(gasPrice float64, gasEffective float64) uint64 {
|
| 698 |
-
if gasPrice > 0 {
|
| 699 |
-
return uint64(((gasEffective*256)+gasPrice-1)/gasPrice - 1) // nolint:gomnd
|
| 700 |
} else {
|
| 701 |
-
|
| 702 |
}
|
| 703 |
}
|
| 704 |
|
| 705 |
-
func roundEffectiveGasPrice(gasPrice float64, pct uint64) float64 {
|
| 706 |
-
return gasPrice / 256 * float64(pct+1) // nolint:gomnd
|
| 707 |
-
}
|
| 708 |
-
|
| 709 |
// calcEffectiveGasPrice calculates the effective gas price
|
| 710 |
func calcEffectiveGasPrice(gasUsed float64, tx *egpLogRecord, cfg *egpConfig) (float64, error) {
|
| 711 |
-
// Decode tx
|
| 712 |
-
rawBytes, err := decodeTx(tx)
|
| 713 |
-
if err != nil {
|
| 714 |
-
return 0, err
|
| 715 |
-
}
|
| 716 |
-
|
| 717 |
-
// Zero and non zero bytes
|
| 718 |
-
txZeroBytes := uint64(bytes.Count(rawBytes, []byte{0}))
|
| 719 |
-
txNonZeroBytes := uint64(len(rawBytes)) - txZeroBytes
|
| 720 |
-
tx.txZeroCount = txZeroBytes
|
| 721 |
-
tx.txNonZeroCount = txNonZeroBytes
|
| 722 |
-
|
| 723 |
// Calculate break even gas price
|
| 724 |
var breakEvenGasPrice float64
|
| 725 |
-
if gasUsed ==
|
| 726 |
-
// Transfer
|
| 727 |
-
if cfg.EthTransferGasPrice != 0 {
|
| 728 |
-
breakEvenGasPrice = float64(cfg.EthTransferGasPrice)
|
| 729 |
-
} else if cfg.EthTransferL1GasPriceFactor != 0 {
|
| 730 |
-
if tx.LogL1GasPrice == 0 {
|
| 731 |
-
breakEvenGasPrice = 1
|
| 732 |
-
} else {
|
| 733 |
-
breakEvenGasPrice = tx.LogL1GasPrice * cfg.EthTransferL1GasPriceFactor
|
| 734 |
-
}
|
| 735 |
-
}
|
| 736 |
-
} else if gasUsed == 0 {
|
| 737 |
breakEvenGasPrice = tx.LogGasPrice
|
| 738 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 739 |
l2MinGasPrice := tx.LogL1GasPrice * cfg.L1GasPriceFactor
|
|
|
|
|
|
|
|
|
|
| 740 |
totalTxPrice := gasUsed*l2MinGasPrice + float64((fixedBytesTx+txNonZeroBytes)*cfg.ByteGasCost+txZeroBytes*cfg.ZeroGasCost)*tx.LogL1GasPrice
|
| 741 |
breakEvenGasPrice = totalTxPrice / gasUsed * cfg.NetProfitFactor
|
| 742 |
}
|
|
@@ -744,7 +646,7 @@
|
|
| 744 |
// Calculate effective gas price
|
| 745 |
var ratioPriority float64
|
| 746 |
if tx.LogGasPrice > tx.LogL2GasPrice {
|
| 747 |
-
ratioPriority = tx.LogGasPrice / tx.LogL2GasPrice
|
| 748 |
} else {
|
| 749 |
ratioPriority = 1
|
| 750 |
}
|
|
|
|
| 25 |
)
|
| 26 |
|
| 27 |
var (
|
| 28 |
+
showErrors bool
|
| 29 |
+
showLosses bool
|
| 30 |
+
showReprocess bool
|
| 31 |
+
showDetail bool
|
| 32 |
+
showAlways bool
|
| 33 |
+
showOnlyCfg bool
|
|
|
|
|
|
|
|
|
|
| 34 |
)
|
| 35 |
|
| 36 |
const (
|
| 37 |
+
signatureBytes = 65
|
| 38 |
+
effectivePctBytes = 1
|
| 39 |
+
fixedBytesTx = signatureBytes + effectivePctBytes
|
|
|
|
| 40 |
)
|
| 41 |
|
| 42 |
type egpConfig struct {
|
| 43 |
+
ByteGasCost uint64 // gas cost of 1 byte
|
| 44 |
+
ZeroGasCost uint64 // gas cost of 1 byte zero
|
| 45 |
+
NetProfitFactor float64 // L2 network profit factor
|
| 46 |
+
L1GasPriceFactor float64 // L1 gas price factor
|
| 47 |
+
L2GasPriceSugFactor float64 // L2 gas price suggester factor
|
| 48 |
+
FinalDeviationPct uint64 // max final deviation percentage
|
| 49 |
+
MinGasPriceAllowed uint64 // min gas price allowed
|
| 50 |
+
L2GasPriceSugFactorPreEGP float64 // L2 gas price suggester factor (pre EGP)
|
|
|
|
| 51 |
}
|
| 52 |
|
| 53 |
type egpLogRecord struct {
|
| 54 |
l2BlockNum uint64
|
| 55 |
l2BlockReceived time.Time
|
| 56 |
encoded string
|
|
|
|
| 57 |
missingLogInfo bool // Flag if egp_log field is empty
|
|
|
|
|
|
|
|
|
|
| 58 |
LogError string `json:"Error"`
|
| 59 |
LogEnabled bool `json:"Enabled"`
|
| 60 |
LogL1GasPrice float64 `json:"L1GasPrice"` // L1 gas price
|
|
|
|
| 88 |
totalLoss float64 // Total loss gas amount
|
| 89 |
sumGasFinal float64 // Accumulated sum of final gas (to get average)
|
| 90 |
countGasFinal float64 // Count number of accumulated (to get average)
|
| 91 |
+
sumGasPreEGP float64 // Accumulated sum of gas without EGP
|
| 92 |
+
countGasPreEGP float64 // Count number of accumulated pre EGP (to get average)
|
| 93 |
sumFee float64
|
| 94 |
+
sumFeePreEGP float64
|
|
|
|
| 95 |
}
|
| 96 |
|
| 97 |
func main() {
|
|
|
|
| 130 |
Value: false,
|
| 131 |
},
|
| 132 |
&cli.BoolFlag{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
Name: "showalways",
|
| 134 |
Usage: "show always full detailed record",
|
| 135 |
Value: false,
|
| 136 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
&cli.StringFlag{
|
| 138 |
Name: "cfg",
|
| 139 |
Aliases: []string{"c"},
|
|
|
|
| 145 |
Usage: "show only simulation results",
|
| 146 |
Value: false,
|
| 147 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
&cli.StringFlag{
|
| 149 |
Name: "db",
|
| 150 |
Usage: "DB connection string: \"host=xxx port=xxx user=xxx dbname=xxx password=xxx\"",
|
|
|
|
| 164 |
// defaultConfig parses the default configuration values
|
| 165 |
func defaultConfig() (*egpConfig, error) {
|
| 166 |
cfg := egpConfig{
|
| 167 |
+
ByteGasCost: 16, // nolint:gomnd
|
| 168 |
+
ZeroGasCost: 4, // nolint:gomnd
|
| 169 |
+
NetProfitFactor: 1.0, // nolint:gomnd
|
| 170 |
+
L1GasPriceFactor: 0.25, // nolint:gomnd
|
| 171 |
+
L2GasPriceSugFactor: 0.5, // nolint:gomnd
|
| 172 |
+
FinalDeviationPct: 10, // nolint:gomnd
|
| 173 |
+
MinGasPriceAllowed: 1000000000, // nolint:gomnd
|
| 174 |
+
L2GasPriceSugFactorPreEGP: 0.1, // nolint:gomnd
|
|
|
|
| 175 |
}
|
| 176 |
|
| 177 |
viper.SetConfigType("toml")
|
|
|
|
| 242 |
showDetail = ctx.Bool("showdetail")
|
| 243 |
showAlways = ctx.Bool("showalways")
|
| 244 |
showOnlyCfg = ctx.Bool("onlycfg")
|
|
|
|
|
|
|
|
|
|
| 245 |
|
| 246 |
// Load simulation config file
|
| 247 |
var err error
|
|
|
|
| 270 |
|
| 271 |
// Query data
|
| 272 |
query := fmt.Sprintf(`
|
| 273 |
+
select lb.received_at, t.l2_block_num, coalesce(t.egp_log::varchar,'') as egp_log, t.encoded
|
| 274 |
from state.transaction t
|
| 275 |
join state.l2block lb on lb.block_num = t.l2_block_num
|
| 276 |
where t.l2_block_num >= %d and t.l2_block_num <= %d`, fromBlock, toBlock)
|
|
|
|
| 286 |
logf("Starting from L2 block %d...", fromBlock)
|
| 287 |
var blockReceived time.Time
|
| 288 |
var l2Block uint64
|
| 289 |
+
var egpLog, encoded string
|
| 290 |
+
var stats, simulateStats egpStats
|
| 291 |
var timeFirst, timeLast time.Time
|
|
|
|
| 292 |
|
| 293 |
i := uint64(0)
|
| 294 |
for rows.Next() {
|
| 295 |
// Fetch row
|
| 296 |
+
err = rows.Scan(&blockReceived, &l2Block, &egpLog, &encoded)
|
| 297 |
if err != nil {
|
| 298 |
logf("Error fetching row: %v", err)
|
| 299 |
return err
|
|
|
|
| 318 |
i++
|
| 319 |
|
| 320 |
// Transaction info
|
| 321 |
+
egpData := egpLogRecord{
|
| 322 |
l2BlockReceived: blockReceived,
|
| 323 |
l2BlockNum: l2Block,
|
| 324 |
encoded: encoded,
|
|
|
|
| 325 |
missingLogInfo: egpLog == "",
|
|
|
|
|
|
|
|
|
|
| 326 |
}
|
| 327 |
|
| 328 |
// Check if EGP info is present
|
| 329 |
if egpLog != "" {
|
| 330 |
// Decode EGP log json
|
| 331 |
+
err = json.Unmarshal([]byte(egpLog), &egpData)
|
| 332 |
if err != nil {
|
| 333 |
logf("Error decoding json from egp_log field: %v", err)
|
| 334 |
return err
|
| 335 |
}
|
|
|
|
|
|
|
|
|
|
| 336 |
}
|
| 337 |
|
| 338 |
// Calculate stats
|
| 339 |
+
countStats(i, l2Block, &egpData, &stats, nil)
|
| 340 |
|
| 341 |
// Simulate using alternative config
|
| 342 |
if egpCfg != nil {
|
| 343 |
+
egpSimData := egpData
|
| 344 |
simulateConfig(&egpSimData, egpCfg)
|
| 345 |
+
countStats(i, l2Block, &egpSimData, &simulateStats, egpCfg)
|
| 346 |
}
|
| 347 |
}
|
| 348 |
|
|
|
|
| 353 |
logf("\nPERIOD [%.2f days]: %v ... %v", diff/24, timeFirst, timeLast) // nolint:gomnd
|
| 354 |
if !showOnlyCfg {
|
| 355 |
logf("\nEGP REAL STATS:")
|
| 356 |
+
printStats(&stats)
|
| 357 |
}
|
| 358 |
|
| 359 |
// Print simulation stats results
|
| 360 |
if egpCfg != nil {
|
| 361 |
logf("\nEGP SIMULATION STATS:")
|
| 362 |
printStats(&simulateStats)
|
| 363 |
+
logf("PARAMS: byte[%d] zero[%d] netFactor[%.2f] L1factor[%.2f] L2sugFactor[%.2f] devPct[%d] minGas[%d] L2sugPreEGP[%.2f]", egpCfg.ByteGasCost,
|
| 364 |
+
egpCfg.ZeroGasCost, egpCfg.NetProfitFactor, egpCfg.L1GasPriceFactor, egpCfg.L2GasPriceSugFactor, egpCfg.FinalDeviationPct, egpCfg.MinGasPriceAllowed, egpCfg.L2GasPriceSugFactorPreEGP)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
}
|
| 366 |
|
| 367 |
return nil
|
| 368 |
}
|
| 369 |
|
| 370 |
// countStats calculates and counts statistics for an EGP record
|
| 371 |
+
func countStats(i uint64, block uint64, egp *egpLogRecord, stats *egpStats, cfg *egpConfig) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
// Show record information
|
| 373 |
if showAlways {
|
| 374 |
+
printEgpLogRecord(egp, false)
|
| 375 |
}
|
| 376 |
|
| 377 |
// Total transactions
|
|
|
|
| 383 |
if showErrors {
|
| 384 |
fmt.Printf("egp-error:#%d:(L2 block [%d] %v):%s\n", i, block, egp.l2BlockReceived, egp.LogError)
|
| 385 |
if showDetail && !showAlways {
|
| 386 |
+
printEgpLogRecord(egp, false)
|
| 387 |
}
|
| 388 |
}
|
| 389 |
}
|
|
|
|
| 404 |
if showReprocess {
|
| 405 |
fmt.Printf("egp-reprocess:#%d:(L2 block [%d] %v)\n", i, block, egp.l2BlockReceived)
|
| 406 |
if showDetail && !showAlways {
|
| 407 |
+
printEgpLogRecord(egp, false)
|
| 408 |
}
|
| 409 |
}
|
| 410 |
}
|
|
|
|
| 430 |
// Gas total and average
|
| 431 |
stats.countGasFinal++
|
| 432 |
stats.sumGasFinal += egp.LogValueFinal
|
|
|
|
| 433 |
|
| 434 |
// Gas total and average without EGP
|
| 435 |
var l2SugPreEGP float64
|
|
|
|
| 439 |
l2SugPreEGP = 0.1
|
| 440 |
}
|
| 441 |
|
| 442 |
+
stats.countGasPreEGP++
|
| 443 |
+
stats.sumGasPreEGP += egp.LogL1GasPrice * l2SugPreEGP
|
| 444 |
+
stats.sumFeePreEGP += egp.LogL1GasPrice * l2SugPreEGP * egp.LogGasUsedSecond
|
| 445 |
|
| 446 |
// Loss
|
| 447 |
if egp.LogValueFinal == egp.LogGasPrice {
|
|
|
|
| 463 |
info := fmt.Sprintf("reprocess=%t, final=%.0f, egp1=%.0f, egp2=%.0f, user=%.0f", egp.LogReprocess, egp.LogValueFinal, egp.LogGasUsedFirst, egp.LogGasUsedSecond, egp.LogGasPrice)
|
| 464 |
fmt.Printf("egp-loss:#%d:(L2 block [%d] %v):loss=%.0f:info:%s\n", i, block, egp.l2BlockReceived, loss, info)
|
| 465 |
if showDetail && !showAlways {
|
| 466 |
+
printEgpLogRecord(egp, false)
|
| 467 |
}
|
| 468 |
}
|
| 469 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 470 |
}
|
| 471 |
}
|
| 472 |
|
|
|
|
| 477 |
}
|
| 478 |
|
| 479 |
// printEgpLogRecord prints values of egpLogRecord struct
|
| 480 |
+
func printEgpLogRecord(record *egpLogRecord, showTxInfo bool) {
|
| 481 |
+
fmt.Printf("L2BlockNum: [%d]\n", record.l2BlockNum)
|
| 482 |
fmt.Printf(" timestamp: [%v]\n", record.l2BlockReceived)
|
|
|
|
| 483 |
fmt.Printf(" Error: [%s]\n", record.LogError)
|
| 484 |
fmt.Printf(" Enabled: [%t]\n", record.LogEnabled)
|
| 485 |
fmt.Printf(" L1GasPrice: [%.0f]\n", record.LogL1GasPrice)
|
|
|
|
| 496 |
fmt.Printf(" Percentage: [%d]\n", record.LogPercentage)
|
| 497 |
fmt.Printf(" MaxDeviation: [%.0f]\n", record.LogMaxDeviation)
|
| 498 |
fmt.Printf(" FinalDeviation: [%.0f]\n", record.LogFinalDeviation)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 499 |
if showTxInfo {
|
| 500 |
fmt.Printf(" encoded: [%s]\n", record.encoded)
|
| 501 |
}
|
|
|
|
| 543 |
fmt.Printf(" Tx fee avg...........: [%.0f] (%.3f GWei) (%.9f ETH)\n", stats.sumFee/stats.countGasFinal,
|
| 544 |
stats.sumFee/stats.countGasFinal/GWEI_DIV, stats.sumFee/stats.countGasFinal/ETH_DIV)
|
| 545 |
}
|
| 546 |
+
if stats.countGasPreEGP > 0 {
|
| 547 |
+
fmt.Printf(" Gas pri.avg preEGP...: [%.0f] (%.3f GWei) (%.9f ETH)\n", stats.sumGasPreEGP/stats.countGasPreEGP,
|
| 548 |
+
stats.sumGasPreEGP/stats.countGasPreEGP/GWEI_DIV, stats.sumGasPreEGP/stats.countGasPreEGP/ETH_DIV)
|
| 549 |
+
}
|
| 550 |
+
if stats.countGasPreEGP > 0 {
|
| 551 |
+
fmt.Printf(" Tx fee avg preEGP....: [%.0f] (%.3f GWei) (%.9f ETH)\n", stats.sumFeePreEGP/stats.countGasPreEGP,
|
| 552 |
+
stats.sumFeePreEGP/stats.countGasPreEGP/GWEI_DIV, stats.sumFeePreEGP/stats.countGasPreEGP/ETH_DIV)
|
| 553 |
+
}
|
| 554 |
+
fmt.Printf(" Diff fee EGP-preEGP..: [%.0f] (%.3f Gwei) (%.9f ETH)\n", stats.sumFee-stats.sumFeePreEGP,
|
| 555 |
+
(stats.sumFee-stats.sumFeePreEGP)/GWEI_DIV, (stats.sumFee-stats.sumFeePreEGP)/ETH_DIV)
|
| 556 |
+
fmt.Printf(" Loss count.......: [%.0f] (%.2f%%)\n", stats.totalLossCount, stats.totalLossCount/statsCount*100) // nolint:gomnd
|
| 557 |
+
fmt.Printf(" Loss total.......: [%.0f] (%.3f GWei) (%.9f ETH)\n", stats.totalLoss, stats.totalLoss/GWEI_DIV, stats.totalLoss/ETH_DIV)
|
| 558 |
if stats.totalLossCount > 0 {
|
| 559 |
+
fmt.Printf(" Loss average.....: [%.0f] (%.0f GWei) (%.9f ETH)\n", stats.totalLoss/stats.totalLossCount, stats.totalLoss/stats.totalLossCount/GWEI_DIV,
|
| 560 |
stats.totalLoss/stats.totalLossCount/ETH_DIV)
|
| 561 |
}
|
|
|
|
| 562 |
}
|
| 563 |
}
|
| 564 |
|
| 565 |
// simulateConfig simulates scenario using received config
|
| 566 |
func simulateConfig(egp *egpLogRecord, cfg *egpConfig) {
|
| 567 |
// L2 and user gas price
|
| 568 |
+
egp.LogL2GasPrice = egp.LogL1GasPrice * cfg.L2GasPriceSugFactor
|
| 569 |
+
egp.LogGasPrice = egp.LogL2GasPrice
|
|
|
|
|
|
|
| 570 |
|
| 571 |
// Compute EGP
|
| 572 |
var err error
|
|
|
|
| 602 |
egp.LogValueFinal = egp.LogGasPrice
|
| 603 |
}
|
| 604 |
}
|
|
|
|
|
|
|
| 605 |
} else {
|
| 606 |
egp.LogValueSecond = 0
|
| 607 |
|
| 608 |
// Final gas: price signed
|
| 609 |
egp.LogValueFinal = egp.LogGasPrice
|
|
|
|
|
|
|
| 610 |
}
|
| 611 |
|
| 612 |
+
// Gas price effective percentage
|
| 613 |
+
if egp.LogGasPrice > 0 {
|
| 614 |
+
egp.LogPercentage = uint64(((egp.LogValueFinal*256)+egp.LogGasPrice-1)/egp.LogGasPrice - 1) // nolint:gomnd
|
|
|
|
|
|
|
|
|
|
|
|
|
| 615 |
} else {
|
| 616 |
+
egp.LogPercentage = 0
|
| 617 |
}
|
| 618 |
}
|
| 619 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 620 |
// calcEffectiveGasPrice calculates the effective gas price
|
| 621 |
func calcEffectiveGasPrice(gasUsed float64, tx *egpLogRecord, cfg *egpConfig) (float64, error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 622 |
// Calculate break even gas price
|
| 623 |
var breakEvenGasPrice float64
|
| 624 |
+
if gasUsed == 0 {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 625 |
breakEvenGasPrice = tx.LogGasPrice
|
| 626 |
} else {
|
| 627 |
+
// Decode tx
|
| 628 |
+
rawBytes, err := decodeTx(tx)
|
| 629 |
+
if err != nil {
|
| 630 |
+
return 0, err
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
// Zero and non zero bytes
|
| 634 |
+
txZeroBytes := uint64(bytes.Count(rawBytes, []byte{0}))
|
| 635 |
+
txNonZeroBytes := uint64(len(rawBytes)) - txZeroBytes
|
| 636 |
+
|
| 637 |
+
// Calculates break even gas price
|
| 638 |
l2MinGasPrice := tx.LogL1GasPrice * cfg.L1GasPriceFactor
|
| 639 |
+
if l2MinGasPrice < float64(cfg.MinGasPriceAllowed) {
|
| 640 |
+
l2MinGasPrice = float64(cfg.MinGasPriceAllowed)
|
| 641 |
+
}
|
| 642 |
totalTxPrice := gasUsed*l2MinGasPrice + float64((fixedBytesTx+txNonZeroBytes)*cfg.ByteGasCost+txZeroBytes*cfg.ZeroGasCost)*tx.LogL1GasPrice
|
| 643 |
breakEvenGasPrice = totalTxPrice / gasUsed * cfg.NetProfitFactor
|
| 644 |
}
|
|
|
|
| 646 |
// Calculate effective gas price
|
| 647 |
var ratioPriority float64
|
| 648 |
if tx.LogGasPrice > tx.LogL2GasPrice {
|
| 649 |
+
ratioPriority = math.Round(tx.LogGasPrice / tx.LogL2GasPrice)
|
| 650 |
} else {
|
| 651 |
ratioPriority = 1
|
| 652 |
}
|
|
@@ -28,20 +28,20 @@
|
|
| 28 |
func main() {
|
| 29 |
// Start containers
|
| 30 |
defer func() {
|
| 31 |
-
cmd := exec.Command("docker
|
| 32 |
if err := cmd.Run(); err != nil {
|
| 33 |
log.Errorf("Failed stop containers: %v", err)
|
| 34 |
return
|
| 35 |
}
|
| 36 |
}()
|
| 37 |
log.Info("Starting DB and prover")
|
| 38 |
-
cmd := exec.Command("docker
|
| 39 |
if out, err := cmd.CombinedOutput(); err != nil {
|
| 40 |
log.Errorf("Failed to star DB: %w. %v", err, out)
|
| 41 |
return
|
| 42 |
}
|
| 43 |
time.Sleep(time.Second * waitForDBSeconds)
|
| 44 |
-
cmd = exec.Command("docker
|
| 45 |
if out, err := cmd.CombinedOutput(); err != nil {
|
| 46 |
log.Errorf("Failed to star prover: %v. %v", err, out)
|
| 47 |
return
|
|
|
|
| 28 |
func main() {
|
| 29 |
// Start containers
|
| 30 |
defer func() {
|
| 31 |
+
cmd := exec.Command("docker-compose", "down", "--remove-orphans")
|
| 32 |
if err := cmd.Run(); err != nil {
|
| 33 |
log.Errorf("Failed stop containers: %v", err)
|
| 34 |
return
|
| 35 |
}
|
| 36 |
}()
|
| 37 |
log.Info("Starting DB and prover")
|
| 38 |
+
cmd := exec.Command("docker-compose", "up", "-d", "executor-tool-db")
|
| 39 |
if out, err := cmd.CombinedOutput(); err != nil {
|
| 40 |
log.Errorf("Failed to star DB: %w. %v", err, out)
|
| 41 |
return
|
| 42 |
}
|
| 43 |
time.Sleep(time.Second * waitForDBSeconds)
|
| 44 |
+
cmd = exec.Command("docker-compose", "up", "-d", "executor-tool-prover")
|
| 45 |
if out, err := cmd.CombinedOutput(); err != nil {
|
| 46 |
log.Errorf("Failed to star prover: %v. %v", err, out)
|
| 47 |
return
|
|
@@ -238,7 +238,7 @@
|
|
| 238 |
|
| 239 |
// Extract coded txs.
|
| 240 |
// Load contract ABI
|
| 241 |
-
abi, err := abi.JSON(strings.NewReader(
|
| 242 |
if err != nil {
|
| 243 |
log.Fatal("error reading smart contract abi: ", err)
|
| 244 |
}
|
|
|
|
| 238 |
|
| 239 |
// Extract coded txs.
|
| 240 |
// Load contract ABI
|
| 241 |
+
abi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI))
|
| 242 |
if err != nil {
|
| 243 |
log.Fatal("error reading smart contract abi: ", err)
|
| 244 |
}
|
|
@@ -32,7 +32,7 @@
|
|
| 32 |
networkFlag = cli.StringFlag{
|
| 33 |
Name: config.FlagNetwork,
|
| 34 |
Aliases: []string{"net"},
|
| 35 |
-
Usage: "Load default network configuration. Supported values: [`
|
| 36 |
Required: false,
|
| 37 |
}
|
| 38 |
customNetworkFlag = cli.StringFlag{
|
|
|
|
| 32 |
networkFlag = cli.StringFlag{
|
| 33 |
Name: config.FlagNetwork,
|
| 34 |
Aliases: []string{"net"},
|
| 35 |
+
Usage: "Load default network configuration. Supported values: [`custom`]",
|
| 36 |
Required: false,
|
| 37 |
}
|
| 38 |
customNetworkFlag = cli.StringFlag{
|
|
@@ -77,7 +77,7 @@
|
|
| 77 |
}
|
| 78 |
|
| 79 |
func newEtherman(c config.Config) (*etherman.Client, error) {
|
| 80 |
-
etherman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config)
|
| 81 |
if err != nil {
|
| 82 |
return nil, err
|
| 83 |
}
|
|
@@ -164,7 +164,7 @@
|
|
| 164 |
stateTree = merkletree.NewStateTree(stateDBClient)
|
| 165 |
}
|
| 166 |
|
| 167 |
-
st := state.NewState(stateCfg, stateDb, executorClient, stateTree, eventLog, nil
|
| 168 |
return st
|
| 169 |
}
|
| 170 |
|
|
|
|
| 77 |
}
|
| 78 |
|
| 79 |
func newEtherman(c config.Config) (*etherman.Client, error) {
|
| 80 |
+
etherman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 81 |
if err != nil {
|
| 82 |
return nil, err
|
| 83 |
}
|
|
|
|
| 164 |
stateTree = merkletree.NewStateTree(stateDBClient)
|
| 165 |
}
|
| 166 |
|
| 167 |
+
st := state.NewState(stateCfg, stateDb, executorClient, stateTree, eventLog, nil)
|
| 168 |
return st
|
| 169 |
}
|
| 170 |
|